update rules

This commit is contained in:
Joe 2026-02-02 14:05:11 -06:00
parent 4c390fdd37
commit d5522b2fef
8549 changed files with 11783 additions and 1888 deletions

View file

@ -0,0 +1,249 @@
---
title: Buy upgrades
description: Part of the Adventure Game Series in Roblox. Code a script to sell items in a Roblox experience.
next: /education/adventure-game-series/finishing-the-project
prev: /education/adventure-game-series/selling-items
---
This brings us to the last stage of the game loop - buying upgrades. By letting players buy upgrades that increase the size of their item bag, they can harvest more items per trip and earn even more gold.
## Create a shop
Each shop will have a button that players click to purchase a larger item bag. The shop itself will be a part with a SurfaceGUI, an item that allows for text to be written on parts.
### Create the sign
1. In the Workspace, create a new model named Shop.
2. In Shop, create a new block part named BuyButton.
<img src="../../assets/education/adventure-game-series/upgrade_partCreate.jpg" />
3. In BuyButton, add a new Surface GUI by clicking the + and scrolling to GUI.
<img src="../../assets/education/adventure-game-series/upgrade_addSurfaceGUI.png" />
4. In Surface GUI, add a new TextLabel named BuyText. A small label will appear somewhere on the part.
<img src="../../assets/education/adventure-game-series/upgrade_showTextLabelAlt.jpg" />
5. Depending on how the part was made, the label can be somewhere else. If you don't see the text on the side you want, go into the SurfaceGUI and find the Face property. Change that property until you see the text label.
<img src="../../assets/education/adventure-game-series/upgrade_changeGUIFace.jpg" />
<Alert severity="warning">
Depending on the part, the Face property might be different than shown above.
</Alert>
### Change the sign text
Right now, the TextLabel is really small and hard for players to see. It needs to be scaled up.
1. In the BuyText properties, click on the arrow next to **Size**. Change the **Offset** for X (left and right) and Y (up and down) to 0.
<img src="../../assets/education/adventure-game-series/upgrade_TextLabelCreate_setOffset.png" />
2. Change the **scale** of X and Y to 0.5 to make a square.
<img src="../../assets/education/adventure-game-series/upgrade_TextLabelCreate_setScale.png" />
3. Scroll up in the TextLabel properties and click the arrow left of **AnchorPoint**. Type in 0.5 for X and Y. This moves part of your label out of view but you'll position it correctly next.
<img src="../../assets/education/adventure-game-series/upgrade_TextLabelCreate_setAnchorPoint.jpg" />
4. Scroll-down in the properties and open **Position**. Change the scale of X and Y to 0.5 so the box is centered in the middle.
<img src="../../assets/education/adventure-game-series/upgrade_TextLabelCreate_setPos.png" />
5. In the BuyText properties, scroll-down and change **Text** to something descriptive. For instance: `"Buy Larger Bag: 100 gold"`.
6. Check **TextScaled** to be **on**. This automatically scales your text so it fits the box.
### Add a click detector
Players will buy items by clicking on the shop rather than just touching it. The script will use a click detector to tell if a player has clicked the shop sign. **ClickDetectors** are objects that allow users to interact with something in the environment, such as opening a door.
1. In the BuyButton, add a ClickDetector.
<img src="../../assets/education/adventure-game-series/upgrade_addClickDetector.png" />
2. In BuyButton, add a new script named BuyScript and give it a descriptive comment.
<img src="../../assets/education/adventure-game-series/upgrade_addScript.png" />
3. In BuyScript, create variables to store the button part and click detector.
```lua
-- Lets players click a button to buy an upgrade that increases Spaces
local buyButton = script.Parent
local clickDetector = buyButton.ClickDetector
```
4. Create a new function named `giveUpgrade()` that gets a parameter named `player`. The function will upgrade a player's spaces whenever they click the button.
```lua
local buyButton = script.Parent
local clickDetector = buyButton.ClickDetector
local function giveUpgrade(player)
end
```
5. After the function, type connect the click detector's `MouseClick` event to the `giveUpgrade()` function.
```lua
local function giveUpgrade(player)
end
clickDetector.MouseClick:Connect(giveUpgrade)
```
6. Add a print statement in `giveUpgrade()` to test the function.
```lua
local function giveUpgrade(player)
print("Someone clicked the button.")
end
```
7. **Play** your project. Click the button and check that you see the text in the Output window.
<img src="../../assets/education/adventure-game-series/adventure-showClickDetector.jpg" />
<Alert severity="info">
Click Detectors have a distance from which players can interact with it. To change this distance, go to the object and modify its MaxActivationDistance.
</Alert>
### Troubleshooting tips
**Issue:** You're unable to click the button or a mouse cursor doesn't appear on the button.
- Make sure that the ClickDetector object is a child of the part you're trying to click on.
- Check that your character is close enough to the button. Or, make sure that the tool is not equipped.
## Buy upgrades
With a working button, it's time to add code into giveUpgrade to remove a player's gold in exchange for an upgraded bag.
### Add upgrade variables
Each upgrade will have two variables: the cost of the upgrade and how many spaces it has.
1. In BuyScript, under `local clickDetector`, create two variables:
- `newSpace`: How many spaces an upgrade adds when purchased.
- `upgradeCost`: The cost of a single upgrade
```lua
-- Variables for the upgrade
local newSpaces = 10
local upgradeCost = 100
```
### Grant upgrades
Before selling the player the upgrade, you need to check if they have enough money. If they do, you'll add to their maximum amount of spaces.
1. In `giveUpgrade()`, type the following below to get the player's leaderstats so you can access their gold and spaces variables.
```lua
local function giveUpgrade(player)
print("Someone clicked the button")
-- Get's the player's leaderboard to get other IntValues
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
-- Gets the player's money and spaces to make changes
local playerGold = playerStats:FindFirstChild("Gold")
local playerSpaces = playerStats:FindFirstChild("Spaces")
end
end
```
<Alert severity="warning">
Make sure the variable names are the same as the ones in the PlayerSetup script.
</Alert>
2. After writing the variables for spaces, create an if statement to if the value of `playerGold` is more or equal to the upgrade cost.
```lua
local function giveUpgrade(player)
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
local playerGold = playerStats:FindFirstChild("Gold")
local playerSpaces = playerStats:FindFirstChild("Spaces")
-- Checks if player has enough money to afford the upgrade
if playerGold and playerSpaces and playerGold.Value >= upgradeCost then
end
end
end
```
3. In the if statement, subtract the upgrade's cost from the player's gold.
```lua
if playerGold and playerSpaces and playerGold.Value >= upgradeCost then
-- Subtract the item's cost from the player's money
playerGold.Value -= upgradeCost
end
```
4. On the next line, add the number of the player's current spaces along with the new spaces granted per upgrade.
```lua
if playerGold and playerSpaces and playerGold.Value >= upgradeCost then
playerGold.Value -= upgradeCost
playerSpaces.Value += newSpaces
end
```
5. Play your project and check the leaderboard to check if the spaces upgrade worked.
<video controls src="../../assets/education/adventure-game-series/adventure-showUpgradePurchase.mp4" width="100%"></video>
### Troubleshooting tips
At this point, the upgrades don't work as intended, try one of the following below.
- Make sure anything in the `()` of `FindFirstChild()` has quotations on **both** sides, like `"leaderstats"`.
- Check that each string in FindFirstChild is the exact same as that IntValue's name in the PlayerSetup script. For example, if your code uses Rubies as money, you should have `FindFirstChild("Rubies")`.
- Make sure that `giveUpgrade()` is above `clickDetector.MouseClick`.
## Complete BuyScript script
A finished version of the script can be referenced below.
```lua
-- Lets players click a button to buy an upgrade that increases MaxSpaces
local buyButton = script.Parent
local clickDetector = buyButton.ClickDetector
-- Variables for the upgrade
local newSpaces = 10
local upgradeCost = 100
local function giveUpgrade(player)
print("Someone clicked the button")
-- Get's the player's leaderboard to get other IntValues
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
-- Gets the player's money and spaces to make changes
local playerGold = playerStats:FindFirstChild("Gold")
local playerSpaces = playerStats:FindFirstChild("Spaces")
-- Checks if player has enough money to afford the upgrade
if playerGold and playerSpaces and playerGold.Value >= upgradeCost then
print("Player can buy item")
-- Subtract the item's cost from the player's money
playerGold.Value -= upgradeCost
playerSpaces.Value += newSpaces
end
end
end
clickDetector.MouseClick:Connect(giveUpgrade)
```

View file

@ -0,0 +1,222 @@
---
title: Code the leaderboard
description: Part of the Adventure Game Series in Roblox. Create a leaderboard in Roblox Studio to track player items.
next: /education/adventure-game-series/collect-items
prev: /education/adventure-game-series/create-the-map
---
In-game, player will have important stats they need to see like the items they've collected. These numbers will be displayed using a leaderboard. **Leaderboards** are built-in features of Roblox that need a script to be activated and customized.
<img src="../../assets/education/adventure-game-series/adventure-leaderboard-finished.jpg" width="70%" />
<Alert severity="info">
Note that the leaderboard in this experience doesn't save player information in-between sessions. For information on saving player data, you'll need to use an advanced coding concept called [data stores](../../cloud-services/data-stores/index.md).
</Alert>
## Set up the leaderboard
Whenever a player is added to the experience, they'll need to be added to the leaderboard along with code for tracking the individual stats.
1. In the Explorer, under **ServerScriptService**, create a new script named PlayerSetup. In that script, delete the hello world line and write a descriptive comment.
<img src="../../assets/education/adventure-game-series/adventure_leaderboard_addtoServerScriptService.png" />
2. After the comment, create a custom function named onPlayerJoin with a parameter named player.
```lua
-- Creates a leaderboard that shows player variables
local function onPlayerJoin(player)
end
```
3. In `onPlayerJoin`, create a variable named `leaderstats`, and have it create a new **Folder** Instance.
```lua
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
end
```
4. Name the new **Folder** instance `leaderstats`, and parent it to the player. Naming the folder `leaderstats` lets Roblox Studio know to create a leaderboard.
```lua
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
end
```
<Alert severity="warning">
Because leaderboards are a built-in feature, they must be named exactly as seen. For example, a folder named "leaderboard" wouldn't work.
</Alert>
5. After the end of the function, connect `OnPlayerJoin` to the `PlayerAdded` event. Whenever a player joins the experience, each player will be provided the leaderboard.
```lua
local Players = game:GetService("Players")
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
end
Players.PlayerAdded:Connect(onPlayerJoin)
```
<Alert severity="warning">
Don't test yet since you won't see a leaderboard. Because there are no stats to display, the leaderboard won't appear.
</Alert>
## Track player stats
Now that a leaderboard is created, it needs to show the player these numbers:
- **Gold** - How much money the player has.
- **Items** - How many items the player has collected from the world.
- **Spaces** - The most items a player can hold at one time.
Each of these numbers will be an IntValue, a placeholder object for a number.
### Code player gold
Start with coding a stat for gold.
1. In `OnPlayerJoin`, under `leaderstats.Parent = player`, type `local gold = Instance.new("IntValue")`. This creates a new IntValue and stores it in the variable gold.
```lua
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
end
```
2. Next, type `gold.Name = "Gold"`. This gives the IntValue a name so you can use it in other scripts. The name will also be shown to players on the leaderboard.
```lua
local function onPlayerJoin(player)
local gold = Instance.new("IntValue")
gold.Name = "Gold"
end
```
<Alert severity="warning">
If you decide to use your own stat names, keep track of their exact name and spelling. They'll be referenced later in the series for other scripts.
</Alert>
3. On a new line, type `gold.Value = 0`. This sets the starting value for players.
```lua
local function onPlayerJoin(player)
local gold = Instance.new("IntValue")
gold.Name = "Gold"
gold.Value = 0
end
```
<Alert severity="info">
While variables are normally changed using `=` as in `myNumber = 10`, an IntValue is changed using `Value`, like `myIntValue.Value = 10`.
</Alert>
4. Type `gold.Parent = leaderstats`. This parents the IntValue for gold to leaderstats. If the IntValue is not parented to leaderstats, players won't see it.
```lua
local function onPlayerJoin(player)
local gold = Instance.new("IntValue")
gold.Name = "Gold"
gold.Value = 0
gold.Parent = leaderstats
end
```
5. Play your project and notice that a leaderboard appears in the top right.
<img src="../../assets/education/adventure-game-series/adventure-leaderboard-empty.jpg" width="70%" />
### Troubleshooting tips
If you don't see the leaderboard, try the following:
- Make sure that `.Value` is capitalized.
- Make sure that the variable for the IntValue is parented to the leaderboard like `gold.Parent = leaderstats`.
### Code items and spaces
Remember that the stat names can be anything based off the game design document. In other words, `"Items"` can be `"Crystals"` instead.
1. Add a blank line to separate the next stat, then create the item stat by setting up a new IntValue the same way you did for gold.
```lua
local function onPlayerJoin(player)
gold.Parent = leaderstats
-- Create the Items stat
local items = Instance.new("IntValue")
items.Name = "Items"
items.Value = 0
items.Parent = leaderstats
end
```
2. Create a new stat for the player's bag spaces. Set `spaces.Value` to `2` so players start the experience only being able to hold two items at once, encouraging them buy a new bag as soon as they can.
```lua
local function onPlayerJoin(player)
items.Parent = leaderstats
-- Create the Spaces stat
local spaces = Instance.new("IntValue")
spaces.Name = "Spaces"
spaces.Value = 2
spaces.Parent = leaderstats
end
```
3. Test the project. Players should have a leaderboard showing Gold, Items, and Spaces.
<img src="../../assets/education/adventure-game-series/adventure-leaderboard-finished.jpg" width="70%" />
If the leaderboard doesn't appear, try checking the following below.
- If you can't see the number on the leaderboard, check that each IntValue is parented to leaderstats.
- Make sure each IntValue is spelled exactly as shown
- Check that the PlayerAdded event is at the bottom of the script
## Complete PlayerSetup script
A finished version of the script can be referenced below.
```lua
local Players = game:GetService("Players")
-- Creates a leaderboard that shows player variables
local function onPlayerJoin(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "Gold"
gold.Value = 0
gold.Parent = leaderstats
local items = Instance.new("IntValue")
items.Name = "Items"
items.Value = 0
items.Parent = leaderstats
local spaces = Instance.new("IntValue")
spaces.Name = "Spaces"
spaces.Value = 2
spaces.Parent = leaderstats
end
-- Run onPlayerJoin when the PlayerAdded event fires
Players.PlayerAdded:Connect(onPlayerJoin)
```

View file

@ -0,0 +1,336 @@
---
title: Collect items
description: Part of the Adventure Game Series in Roblox. Code a tool to collect items.
next: /education/adventure-game-series/selling-items
prev: /education/adventure-game-series/code-the-leaderboard
---
With the leaderboard created, players need something to collect. For that, you need to create a 3D item for players to find in the world. Below is a video of the process of players harvesting items.
<video controls src="../../assets/education/adventure-game-series/adventure-harvestItemShort.mp4" width="100%"></video>
## Build an item
Items in the experience are 3D models that players use a tool to harvest. Each item, once harvested, disappears and then reappears after a limited amount of time.
For the item, refer back to your game design document. This series uses crystals as the example.
1. Create an object, either using parts or objects found by trusted users in the Marketplace.
If desired, download the crystal part with this [link](../../assets/education/adventure-game-series/crystalPart.rbxm). To add it, right-click on the Workspace and select **Insert from File**.
<img src="../../assets/education/adventure-game-series/adventure-item-example.jpg" />
2. If using your own part, group all the parts into a **Model**. One way of doing this is to select all items, right-click on a part, and select **Group**. This creates a model that organizes your parts.
<img src="../../assets/education/adventure-game-series/adventure-show-group.png" />
3. Make sure that the parts are all **anchored**.
4. So items cannot be harvested while they disappear, create a **BoolValue** named CanHarvest to track its status.
<img src="../../assets/education/adventure-game-series/createdBoolValue.png" />
5. In Properties for CanHarvest, check the **Value** box. Checking the value box makes the boolean true, meaning players can harvest the item.
<img src="../../assets/education/adventure-game-series/adventure-show-boolTrue.png" />
## Create a tool
Players need something like an ax or a shovel to gather items with. In Roblox, items that players can equip and use are called **tools**. This lesson uses a starter tool with all the parts and an animation already made that you can customize later.
<img src="../../assets/education/adventure-game-series/adventure-toolWithPlayer.jpg" />
### Add the tool
For players to use the starter tool, download and place it in the StarterPack.
1. Download the starter tool below.
<a href="../../assets/education/adventure-game-series/starterTool.rbxm">
<Button variant="contained">Download Tool</Button>
</a>
2. In Explorer, under Workspace, right-click on StarterPack. Then, select **Insert from File**.
<img src="../../assets/education/adventure-game-series/tools_starterPackClick.png" />
3. Select the downloaded file, `starterTool.rbxm`.
4. Playtest your project. Players should be equipped with the tool as soon as they start. In-game, press <kbd>1</kbd> to equip or put away the tool. Left-click to swing it.
<img src="../../assets/education/adventure-game-series/adventure-toolWithPlayer.jpg" />
<Alert severity="info">
If you want to rename the starter tool, just rename the object in StarterPack. That name displays to players.
</Alert>
## Code the tool
If the tool hits a harvestable object and the player has enough space in their bag, the player's item count goes up by 1 on the leaderboard. Harvesting an item makes it disappear for a few seconds and become unharvestable for a few seconds before reappearing. This encourages players to explore to find more items, instead of just clicking the same item.
### Set up the script
At this point, add a script to the tool. This script handles what happens when the tool touches a harvestable object.
1. In StarterPack, under StarterTool, add a new script named ToolScript.
<img src="../../assets/education/adventure-game-series/adventure-addToolScript.png" />
2. In the script, write a descriptive comment at top, and then create variables to store the tool part and the tool itself.
```lua
-- Gives players item when they touch a harvestable part
local tool = script.Parent
local toolPart = tool.Handle
```
### Check for items
Whenever the tool touches an object, it checks if that object has CanHarvest inside and if the boolean is set to True.
1. Create a new function named `onTouch()` with a parameter named `partTouched`.
```lua
local tool = script.Parent
local toolPart = tool.Handle
local function onTouch(partTouched)
end
```
2. In that function, create a local variable named `canHarvest`. Then, use the `FindFirstChild()` function to see if there is CanHarvest boolean in the parent of that part.
```lua
local function onTouch(partTouched)
local canHarvest = partTouched:FindFirstChild("CanHarvest")
end
```
3. Now the script needs to check if there was actually anything found and if so, run the code. To do this, create an if statement where the condition is `canHarvest`. If anything exists in `canHarvest`, this statement evaluates to true.
```lua
local function onTouch(partTouched)
local canHarvest = partTouched:FindFirstChild("CanHarvest")
if canHarvest then
end
end
```
4. In the if statement, add a print statement to see if the script is working. You can code the logic for harvesting items after you're sure it works.
```lua
if canHarvest then
-- Used for testing if code works
print("Found an item")
end
```
5. Under the function's `end` statement, add `toolPart.Touched:Connect(onTouch)`. This lets the script check if anything is touching the tool (or in this case, its handle) and if so, calls `onTouch()`.
```lua
local function onTouch(partTouched)
local canHarvest = partTouched:FindFirstChild("CanHarvest")
if canHarvest then
print("Found an item")
end
end
toolPart.Touched:Connect(onTouch)
```
6. Play the project and use the tool on a harvestable item (left-click to swing). Make sure you see the message "Found an item" in the Output window.
<img src="../../assets/education/adventure-game-series/adventure-testedTool.jpg" />
### Troubleshooting tips
If you don't see the message, try the following tips.
- If you're using custom parts and meshes, it's possible to get an error. The script only works if the CanHarvest object is a child of the part the tool is touching.
- Make sure that the tool is in the StarterPack, not in the Workspace.
- Check that the part is anchored.
### Get player stats
Before increasing the player's items, the tool must find the location of how many items a player has in that player's leaderboard. Once the tool has access to the leaderboard, it can change that player's item count.
1. First, get the player using the tool. In the ToolScript, under `local item = toolitem`, and above the custom function, type:
```lua
local item = toolitem
local backpack = tool.Parent
local player = backpack.Parent
local function onTouch(partTouched)
```
2. On the next line, find the player's leaderstats using the `FindFirstChild()` function.
```lua
local backpack = tool.Parent
local player = backpack.Parent
local playerStats = player:FindFirstChild("leaderstats")
local function onTouch(partTouched)
```
3. Under `local playerStats`, create variables to store the items and spaces stats.
```lua
local playerStats = player:FindFirstChild("leaderstats")
local playerItems = playerStats:FindFirstChild("Items")
local playerSpaces = playerStats:FindFirstChild("Spaces")
```
<Alert severity="warning">
The strings inside the `()` for `FindFirstChild()` need to be the **same** as the IntValue names in the PlayerSetup script. If you had a different name for the items, make sure it's the same as in the PlayerSetup script.
</Alert>
### Check for a harvestable object
Now that the tool script has the playerItems and playerSpaces variables created, you can start giving players an item. Use the function created to check if the object touching the tool can be harvested, and if the player has enough space in their bag to increase the items shown on the leaderboard by one.
1. The script will need an if statement with two conditions to be met. Start by creating an if statement, then add in the following conditions, connected with the `and` keyword. .
- `canHarvest.Value == true`
- `playerItems.Value < playerSpaces.Value`
```lua
local function onTouch(partTouched)
local canHarvest = partTouched.Parent:FindFirstChild("CanHarvest")
if canHarvest then
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
end
end
end
```
<Alert severity="info">
To access the contents of any value object, type .Value at the end of it. If you just do the object itself, you'll just get it's name.
</Alert>
2. In the if statement itself, add to the player's items by typing `playerItems.Value += 1`.
```lua
if canHarvest then
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
playerItems.Value += 1
end
end
```
3. Play your project; use your tool to harvest an item and check that the item count went up.
<img src="../../assets/education/adventure-game-series/adventure-leaderboard-withItem.jpg" />
<Alert severity="warning">
Right now, the player's Items stat will **instantly** fill up after hitting one item. In the next section, you'll make the item reset so players only get one item from each item.
</Alert>
### Reset the item
When the item is harvested, it will reset in two ways:
- The item will disappear and not be interactable
- CanHarvest set to false
The item will then go back to normal after a short time. This way, players only get one item for each harvest, and need to look around for more while the original resets.
1. Under where items are added, set `canHarvest` to false. By making the value of `canHarvest` false as soon as players harvest the item, the script won't give more than one item per tool hit.
```lua
if canHarvest then
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
playerItems.Value += 1
canHarvest.Value = false
end
end
```
2. After setting the value to false, set the part's Transparency to 1 (invisible), and CanCollide to false, meaning players can't touch it.
```lua
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
playerItems.Value += 1
canHarvest.Value = false
partTouched.Transparency = 1
partTouched.CanCollide = false
end
```
3. Type `task.wait(5)` to give time for the item to reset. 5 is a suggested number, and maybe differ for how long you'd like for your experience.
```lua
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
playerItems.Value += 1
canHarvest.Value = false
partTouched.Transparency = 1
partTouched.CanCollide = false
task.wait(5)
end
```
4. After the wait, do the opposite of previous code, by setting the CanHarvest to true, and resetting the Transparency and CanCollide to their original values.
```lua
task.wait(5)
canHarvest.Value = true
partTouched.Transparency = 0
partTouched.CanCollide = true
end
```
5. Play the project and check:
- The player only gets 1 item for harvesting an item.
- The item disappears and then reappears after five seconds.
<video controls src="../../assets/education/adventure-game-series/adventure-harvestItemFull.mp4" width="100%"></video>
### Troubleshooting tips
At this point, if one of the checks didn't pass try one of the following below.
- Check that Transparency and CanCollide are spelled and capitalized exactly.
- Make sure to use canHarvest.Value and not canHarvest = true.
## Complete ToolScript
A finished version of the script can be referenced below.
```lua
local toolPart = script.Parent
local tool = toolPart.Parent
local backpack = tool.Parent
local player = backpack.Parent
local playerStats = player:FindFirstChild("leaderstats")
local playerItems = playerStats:FindFirstChild("Items")
local playerSpaces = playerStats:FindFirstChild("Spaces")
local function onTouch(partTouched)
local canHarvest = partTouched:FindFirstChild("CanHarvest")
if canHarvest then
if canHarvest.Value == true and playerItems.Value < playerSpaces.Value then
playerItems.Value += 1
canHarvest.Value = false
-- Reset partTouched, the harvested item
partTouched.Transparency = 1
partTouched.CanCollide = false
task.wait(5)
-- Make the harvested item reappear and usable again
canHarvest.Value = true
partTouched.Transparency = 0
partTouched.CanCollide = true
end
end
end
toolPart.Touched:Connect(onTouch)
```

View file

@ -0,0 +1,123 @@
---
title: Create the map
description: Part of the Adventure Game Series in Roblox. Learn how to use terrain tools in Roblox Studio.
next: /education/adventure-game-series/code-the-leaderboard
prev: /education/adventure-game-series/landing
---
<img src="../../assets/education/adventure-game-series/heroBanner_titlePage.jpg" width="75%" />
Adventure games can come in different forms but often focus on getting a player to explore a world. This experience will be all about exploring, harvesting items, selling them, upgrading bags, and then doing it all over again. This cycle of actions is called a **game loop**.
Each part of the game loop is a different game mechanic, or action, players can do. This game loop has four mechanics:
- **Explore** the experience to find items.
- **Harvest** items. Players can only hold so many at a time.
- **Sell** items for gold.
- **Buy** bag upgrades to holds more items at a time.
## Plan the project
Before professional developers start a new project, they plan out what things will look like in a process called **pre-production**. They'll often create a game design document that includes how the experience works.
While **game design documents** (GDDs) can often be long, for this series, you'll start with a vision of what players will do and sketches of the world they'll explore. Having a clear vision helps speed up development and also make it easier to communicate your ideas to get feedback from others.
### Create a game design document
To start, get a piece of paper or open up a word editor to keep track of the document.
### Game loop prompts
The following are used to help you figure out the game loop, or what players will be doing.
<table>
<thead>
<tr>
<th width="30%">Component</th>
<th>Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td><b>Setting</b>: A description of the setting, such as a theme or what players will see when exploring. </td>
<td>
- A mystical forest covered in trees and rivers.
- A suburban town where you need to collect lost pets.
- A future where the most valuable object is a potato.
</td>
</tr>
<tr>
<td><b>Items</b>: What players gather or harvest. </td>
<td>
- Glittering crystals.
- Lost pets like cats, dogs, and turtles.
- Different types of potatoes.
</td>
</tr>
<tr>
<td><b>Tools</b>: The object players use to collect that item.</td>
<td>
- Pickaxes.
- Pet collars.
- Gloves.
</td>
</tr>
<tr>
<td><b>Upgrades</b>: What players will buy to hold more items.</td>
<td>
- Bags
- Backpacks
</td>
</tr>
</tbody>
</table>
### Map layouts
The last part of the game design document is to create the map layout. This gives you an idea of what to create later. An example layout is below.
<img src="../../assets/education/adventure-game-series/paintToolOptimized.gif" width="50%" />
In the layout, annotate these key places:
- Where players start the experience.
- Placement of the harvestable items.
- Where players will sell items.
- Where players will buy upgrades.
- Environment details, such as grasslands, hills, and more.
## Create the environment
The environment will be created using the **Terrain Editor**. This tool in Roblox Studio is used to create landscapes like mountains, rivers, or deserts. While using the tools, reference the map layout previously created.
You'll use the tools in the Terrain Editor to create the world you drew in your game vision document.
1. Open Studio and create a new **Flat Terrain** project.
2. In the **Home** tab, click the **Terrain** button. This opens the **Terrain Editor** on the left of the screen.
3. In the Terrain Editor, go to the **Edit** tab. Then use the **Paint** tool to change the material of the landscape. Depending on your vision, paint in roads, water, or even lava.
<img src="../../assets/studio/terrain-editor/Edit-Tab-Paint.png" width="360" alt="Paint tool indicated in Edit tab of Terrain Editor" />
<img src="../../assets/education/adventure-game-series/paintToolOptimized.gif" width="50%" />
<Alert severity="info">
While using the terrain editor, rotate the camera as you build. Terrain might look differently from different angles.
</Alert>
4. Use the **Draw** tool to draw the setting you created in your vision document. Use the **Brush Mode** toggle to switch between adding and subtracting terrain.
<img src="../../assets/studio/terrain-editor/Edit-Tab-Draw.png" width="360" alt="Draw tool indicated in Edit tab of Terrain Editor" />
- Add terrain to create mountains, hills, and break up grasslands.
<img src="../../assets/education/adventure-game-series/addToolExample.gif" width="80%" />
- Subtract terrain to sculpt mountains, create sharper features like cliffs, or carve rivers.
<img src="../../assets/education/adventure-game-series/subtractToolExample.gif" width="50%" />
## Finished map sample
Once finished, your map might look like the following.
<img src="../../assets/education/adventure-game-series/adventureGameTerrain02.jpg" width="50%" />

View file

@ -0,0 +1,60 @@
---
title: Finish the project
description: Part of the Adventure Game Series in Roblox. Finish the project by adjusting scripts.
next:
prev: /education/adventure-game-series/buying-upgrades
---
Your experience is almost ready for others to play! Before sharing, you'll make some small changes to scripts, build out your world a bit more, and then play-test your experience.
## Start player variables
While making the experience, many variables were set to small values, like the player's starting spaces was 2. While this made it easy to test, this might not be the right number for players in their final experience.
Before sharing your experience with others, it's important that the variables feel **challenging**, but **fair**. Getting the right numbers for an experience will give players a more fun experience.
1. In ServerScriptService > PlayerSetup change the value of `Spaces`. Remember this is how many spaces a player has to hold items before they must sell them. A number between 6-10 is a good starting point, but play-testing for the right amount is best.
```lua
local maxSpaces = Instance.new("IntValue")
maxSpaces.Name = "Spaces"
-- 6 as a possible value for a player's bag
maxSpaces.Value = 6
```
2. In SellPart > SellScript, change the value of how much players get for each item. This is the number multiplied by `playerItems.Value`. Try a number between 50 and 200.
```lua
local totalSell = playerItems.Value * 200
```
3. In Shop > BuyButton > BuyScript, change the starting values in the variables for `newMaxItems` (recommended 10-15) and `upgradeCost` (recommended 500-1000).
```lua
-- Possible values for a game
local newMaxItems = 15
local upgradeCost = 500
```
## Add more items
Where you place your items will affect how much fun a player has getting them. Different placements and obstacles to getting items are two ways of making item collection more fun.
<img src="../../assets/education/adventure-game-series/map-crystals.jpg" />
## Playtesting and feedback
Each number that a game designer uses for something in their experience is an educated guess based on what might be fun. Each part of your experience should be challenging, but fair.
Giving a player 10 spaces to start with might sound fun, but you don't really know until you test out the project. Always test to see if it feels fun, and ask friends to play-test it as well. As you play-test, think about these questions.
- Does the player have to walk a lot to find an item or are they too easy to find?
- Does the cost of upgrading feel too easy or too hard?
- Are there any bugs that you didn't notice?
## Expand the experience
Although you've finished the course, there are many ways you can continue adding to your experience using the skills you've learned:
- Make more than one item for players to collect
- Create different types of upgrades

View file

@ -0,0 +1,90 @@
---
title: Create an adventure game
description: How to make a game in Roblox Studio. Learn to design and code an adventure experience for Roblox as a beginner.
next: /education/adventure-game-series/create-the-map
prev:
---
### Series description
Create an adventure game where players explore a world to find items to harvest and sell. Perfect for those who have already have some familiarity with Roblox Studio and basic coding concepts up to if/then statements.
<video controls src="../../assets/education/adventure-game-series/adventure-game-examplevideo.mp4" width="100%"></video>
### Objectives and prerequisites
<table>
<tbody>
<tr>
<td width="20%"><b>Learning Objectives</b></td>
<td>
Apply knowledge of common coding concepts, such as variables, if statements, and functions to create scripts.
Practice the design process by pre-planning, designing, and then testing to iterate and improve an experience.
</td>
</tr>
<tr>
<td><b>Prerequisites</b></td>
<td>
Have an understanding of the following Luau concepts: variables, conditional (if/else) statements, and typing functions.
Feel comfortable working with the world creation tools in Roblox, such as making parts or creating terrain.
</td>
</tr>
</tbody>
</table>
### Series contents
<table>
<thead>
<tr>
<th>Article</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="../../education/adventure-game-series/create-the-map.md">Create the Map</a></td>
<td>Go into pre-planning by creating a game design document, then using it to design a map with Roblox terrain tools.</td>
</tr>
<tr>
<td><a href="../../education/adventure-game-series/code-the-leaderboard.md">Code the Leaderboard</a></td>
<td>Create a script that manages items players collect in the experience.</td>
</tr>
<tr>
<td><a href="../../education/adventure-game-series/collect-items.md">Making Collecting Items</a></td>
<td>Design an item for players to gather, then create and code a tool so they can harvest it</td>
</tr>
<tr>
<td><a href="../../education/adventure-game-series/selling-items.md">Selling Items</a></td>
<td>Use Touch events in scripts to create a part that allows players to seel their items for currency.</td>
</tr>
<tr>
<td><a href="../../education/adventure-game-series/buying-upgrades.md">Buying Upgrades</a></td>
<td>Learn how to use click detectors to create a button where players can buy upgrades to give them more space for items.</td>
</tr>
<tr>
<td><a href="../../education/adventure-game-series/finishing-the-project.md">Finishing the Project</a></td>
<td>Some final steps to wrap up the project, as well as tips on how to expand and improve. </td>
</tr>
</tbody>
</table>
### Example project
<table>
<tbody>
<tr>
<td><img src="../../assets/education/adventure-game-series/adventure-gameThumbnail.jpg" /></td>
<td>
[Adventure Game Example](https://www.roblox.com/games/9544298367/)
Play an version of the final project to see what you can develop with this series.
</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,210 @@
---
title: Sell items
description: Part of the Adventure Game Series in Roblox. Code how to sell items in a Roblox experience.
next: /education/adventure-game-series/buying-upgrades
prev: /education/adventure-game-series/collect-items
---
<img src="../../assets/education/adventure-game-series/adventure-sellingItemsHero.jpg" width="100%" />
For the next stage of the game loop, players need to sell their items for gold to allow them to purchase more space in their backpacks.
## Create a sell platform
Players will sell their items by stepping onto a platform that gives them gold for each item in their bag.
### Set up the platform
The platform can be any part and will include a script that handles selling.
1. Create a new part named SellPlatform. Customize it to fit the theme of your experience.
<img src="../../assets/education/adventure-game-series/adventure-sellPlatform.jpg" />
2. In SellPlatform, create a new script named SellScript and add a comment.
<img src="../../assets/education/adventure-game-series/adventure-showSellScript.png" />
3. In SellScript, type `local sellPart = script.Parent` to get the SellPlatform part.
```lua
-- Sells all a player's items and gives them gold
local sellPart = script.Parent
```
### Handle touch events
To use the platform, the script needs a function to check if any players touch it.
1. Create a function named `onTouch()` that checks if a player is touching the platform.
```lua
local function onTouch(partTouched)
local character = partTouched.Parent
end
```
2. To change any of the stats on the leaderboard, the script needs to know what player is controlling the character. In the if statement, use the `GetPlayerFromCharacter()` function to find a player.
```lua
local Players = game:GetService("Players")
local player = Players:GetPlayerFromCharacter(character)
```
3. On the next line, get that player's leaderstats container.
```lua
local Players = game:GetService("Players")
local player = Players:GetPlayerFromCharacter(character)
if player then
-- Gets the player's leaderboard. Needed to get items and money
local playerStats = player:FindFirstChild("leaderstats")
end
```
4. On the next line, create variables to get the player's money and items.
```lua
local Players = game:GetService("Players")
local player = Players:GetPlayerFromCharacter(character)
if player then
-- Gets the player's leaderboard. Needed to get items and money
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
-- Gets the player's items and money
local playerItems = playerStats:FindFirstChild("Items")
local playerGold = playerStats:FindFirstChild("Gold")
end
end
```
<Alert severity="warning">
Make sure the names of everything in `FindFirstChild()` is exactly like the names written in the PlayerSetup script. For example, if your money is "Rubies" in PlayerSetup, playerGold should look for "Rubies" instead of "Gold".
</Alert>
5. To check your work, add a print statement that will run if a player touched sellPart.
```lua
local playerItems = playerStats:FindFirstChild("Items")
local playerGold = playerStats:FindFirstChild("Gold")
print("A player touched sellPart")
```
6. At the bottom of the script, connect the `onTouch()` to sellPart's Touched event.
```lua
local Players = game:GetService("Players")
local function onTouch(partTouched)
local character = partTouched.Parent
local player = Players:GetPlayerFromCharacter(character)
if player then
-- Gets the player's leaderboard. Needed to get items and money
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
-- Gets the player's items and money
local playerItems = playerStats:FindFirstChild("Items")
local playerGold = playerStats:FindFirstChild("Gold")
print("A player touched sellPart")
end
end
end
sellPart.Touched:Connect(onTouch)
```
7. Play your project and step on sellPart; you should see the message `"A Player touched sellPart"` in the Output window.
## Sell items
In this experience, a player will get 100 Gold for each item. After getting money, their items will be set back to 0, letting players explore the world for more items.
### Code a new sell function
1. Under the variables, create a function named `sellItems()` that gets two parameters named `playerItems` and `playerGold`.
```lua
-- Sells all a player's items and gives them gold
local sellPart = script.Parent
local function sellItems(playerItems, playerGold)
end
local function onTouch(partTouched)
```
2. To give players the right amount of gold, take the value of the `playerItems` and multiply it by the amount of gold they should receive per item. This example gives one hundred gold pieces per item.
In the `sellItems()` function, type `local totalSell = playerItems.Value * 100`
```lua
local function sellItems(playerItems, playerGold)
-- Gets how many items the player has and multiplies that by item worth.
local totalSell = playerItems.Value * 100
end
```
3. Type `playerGold.Value += totalSell` to add the gold for the items to their current gold.
```lua
local function sellItems(playerItems, playerGold)
local totalSell = playerItems.Value * 100
-- Add how much the player earns to their money
playerGold.Value += totalSell
end
```
4. Type `playerItems.Value = 0`. This sets a player's items back to 0. If a player's items aren't set back to 0, the script will keep giving players gold without stopping.
```lua
local function sellItems(playerItems, playerGold)
local totalSell = playerItems.Value * 100
playerGold.Value += totalSell
playerItems.Value = 0
end
```
5. In the `onTouch()` function, **under the second if statement**, call the `sellItems()` function. Pass in the parameters, `playerItems` and `playerGold` so they can be changed.
```lua
local Players = game:GetService("Players")
local player = Players:GetPlayerFromCharacter(character)
if player then
-- Gets the player's leaderboard. Needed to get items and money
local playerStats = player:FindFirstChild("leaderstats")
if playerStats then
-- Gets the player's items and money
local playerItems = playerStats:FindFirstChild("Items")
local playerGold = playerStats:FindFirstChild("Gold")
if playerItems and playerGold then
sellItems(playerItems, playerGold)
end
end
end
```
6. Play your project; check that whenever a player steps on the platform, their gold increases and items are set to 0.
<video controls src="../../assets/education/adventure-game-series/adventure-sellItems.mp4" width="100%"></video>
### Troubleshooting Tips
At this point, selling items doesn't work as intended, try one of the following below.
- `sellItems()` is called in the **second** if statement that checks the player's items.
- Any IntValue, like playerItems, uses .Value at the end if you're making a change to it. Value is always capitalized.
- `sellPart.Touched:Connect(onTouch)` is typed at the **bottom** of the script.
- `sellItems(playerItems, playerGold)` is typed before the end of the if humanoid then statement.