Stage 6: Hidden Hazard Field + reveal wave
Make sure you've finished Stage 5: Fireball Cannon + player launcher. You'll reuse your Stage 4 KillBricks scan and the GetUserCFrame hand-reading from Stage 1 — both should already be in your game.
a field of faint, deadly tiles crossed with bounce pads
how one good scan powers new hazards for free, and how to reveal danger with your hand
a hazard field you scout by waving your VR hand to light up the hidden tiles
The big idea
This stage is a test of nerve: a field of tiles where some are deadly — and they're nearly invisible. On a screen you can just make out faint ghostly tiles; you cross by reading them carefully and using bounce pads to leap the worst clusters.
Here's the satisfying part: you barely write any new code. In Stage 4 you built a Killer scan that makes any tagged part deadly. So to make these hazards kill, you just tag them Killer — your old script already handles the rest. That's the whole reward of a good pattern: new content, no new wiring. (Stage 4's Connect prompt promised you this exact moment.)
The VR half is a brand-new sense: the reveal wave. Sweep your hand across the field and any hidden tile your hand passes near lights up bright and solid — like running your palm over a wall to feel for a hidden door. You scout the safe lane with your arm before you ever step. It reuses the hand-reading from Stage 1 and the smooth easing from Stage 5; you're combining three old ideas into something that feels totally new.
- Transparency
- how see-through a part is: 0 is solid, 1 is invisible; 0.7 is a faint ghost
- attribute (Hidden)
- a second tag, separate from Killer, marking which parts the reveal wave should light up
- reuse
- letting code you already wrote handle new things — here, the Killer scan powers new hazards with zero edits
- proximity
- nearness; we light a tile when your hand's distance to it is small
- ease (lerp)
- sliding a value toward a target a little each frame for a smooth fade — the Stage 5 pattern again
Build it
Step 1 — Build the hazard field
A wide thin floor, studded with faint deadly tiles.
Build this partHazardField
BlockOpen recipe
HazardField
Block- Size
- 30 × 1 × 24
- Color
- Dark stone grey
- Material
- Slate
- Anchored
- ✓ Yes
- Place
- Just past the Stage 6 pad — the floor you cross
This floor is safe to walk. The danger sits on top of it.
Now place several deadly tiles flush on top of the field. Make them faint so they're a real challenge to spot. Build four to six.
Build this partHazard_1
BlockOpen recipe
Hazard_1
Block- Size
- 4 × 1 × 4
- Color
- Really red
- Material
- Neon
- Anchored
- ✓ Yes
- Place
- Somewhere on the HazardField, flush with its top
Set Transparency to 0.7 (faint). After building, add TWO attributes in Step 1.1.
Build this partHazard_2
BlockOpen recipe
Hazard_2
Block- Size
- 4 × 1 × 4
- Color
- Really red
- Material
- Neon
- Anchored
- ✓ Yes
- Place
- Elsewhere on the field — leave a weaving safe path between tiles
Repeat for Hazard_3, Hazard_4, and as many more as you like (Hazard_5, Hazard_6). Scatter them so there's a winding safe route, but make it tight enough to be scary. Set every hazard's Transparency to 0.7.
1.1 Tag every hazard with TWO attributes
Each hazard needs two labels: one to make it deadly (reusing Stage 4), one to make it revealable.
- Select Hazard_1. In Properties → Attributes, add:
- Name:
Killer. Type:boolean. Value: checked (true). - Name:
Hidden. Type:boolean. Value: checked (true).
- Name:
- Do the same for every other hazard tile.
Killer makes it deadly (old code). Hidden marks it for the reveal wave (new code).
Step 2 — Make them deadly with NO new script
Press ▶ Play and step on a faint red tile. You die and respawn.
You didn't write a kill script. Your Stage 4 KillBricks script scans for every Killer part when the game starts — these new tiles match, so they're already deadly. This is the payoff of the pattern: you added a whole new hazard type by ticking one checkbox.
Either the tile is missing its Killer attribute, or your KillBricks script from Stage 4 isn't in ServerScriptService. The scan only catches parts that exist when it runs, so build your tiles before pressing Play.
Step 3 — Add bounce pads
Bounce pads help you leap a tight cluster of hazards. This is the same idea as your Stage 2 jump pad — reuse the pattern.
Build this partBouncePad_1
BlockOpen recipe
BouncePad_1
Block- Size
- 5 × 1 × 5
- Color
- Lime green
- Material
- Neon
- Anchored
- ✓ Yes
- Place
- On a safe spot in the field, before a tricky cluster
Insert a server Script into BouncePad_1:
local pad = script.Parent
local BOUNCE_POWER = 75
local onCooldown = {}
pad.Touched:Connect(function(hit)
local character = hit.Parent
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
local root = character and character:FindFirstChild("HumanoidRootPart")
if not (humanoid and root) then return end
if onCooldown[character] then return end
onCooldown[character] = true
local v = root.AssemblyLinearVelocity
root.AssemblyLinearVelocity = Vector3.new(v.X, BOUNCE_POWER, v.Z)
task.wait(0.4)
onCooldown[character] = nil
end)
Add a second bounce pad or two if your field is wide. Press ▶ Play and bounce over a cluster. Recognize this script? It's your jump pad with a new name — you're reusing what you already know.
Step 4 — Place the Stage 7 checkpoint
- Insert a SpawnLocation on the far side of the field. Size
[6, 1, 6], anchored, a new color (try Deep orange). Check AllowTeamChangeOnTouch, uncheck Neutral, match TeamColor. - Add a
StageNumberattribute (number) = 7. - Add a Team named Stage 7, matching TeamColor, AutoAssignable unchecked.
Cross the field, touch the pad, reset — you should respawn there.
Step 5 — Add the VR reveal wave
Open VRController. This reads your right hand each frame and brightens any Hidden tile your hand sweeps near. It reuses the hand-to-world math from Stage 1 and the easing from Stage 5. Paste at the bottom:
-- ===== VR hazard reveal wave (added in Stage 6) =====
local REVEAL_RANGE = 8 -- how close your hand must sweep to light a tile
local FAINT = 0.7 -- resting transparency (matches what you set in Studio)
-- Find every tile tagged Hidden, once.
local hiddenTiles = {}
for _, part in ipairs(workspace:GetDescendants()) do
if part:IsA("BasePart") and part:GetAttribute("Hidden") then
table.insert(hiddenTiles, part)
end
end
RunService.RenderStepped:Connect(function()
if not VRService.VREnabled then return end
local handCFrame = camera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.RightHand)
local handPos = handCFrame.Position
for _, tile in ipairs(hiddenTiles) do
local near = (tile.Position - handPos).Magnitude <= REVEAL_RANGE
local target = near and 0 or FAINT -- near: solid, else: faint
tile.Transparency = tile.Transparency + (target - tile.Transparency) * 0.2
end
end)
Press ▶ Play on your laptop. The tiles stay faint, Output stays clean — there's no headset hand to sweep, so the loop is skipped. That clean run is today's pass; the reveal lights up at the Stage 10 playtest.
Standing at the edge of the field, sweep your hand out over the tiles like you're brushing a table. Every hidden tile your palm passes near flares bright and solid for a moment, then fades back to a ghost as your hand moves on. You map the safe lane with your arm before you commit a single step — danger you can feel out, not just guess at.
How the reveal wave lights danger near your hand
Three old ideas, one new feel: the attribute scan (Stage 1/4), the hand-to-world position (Stage 1), and the smooth ease (Stage 5). Notice you didn't learn a single new structure — you recombined.
local REVEAL_RANGE = 8
local FAINT = 0.7
local hiddenTiles = {}
for _, part in ipairs(workspace:GetDescendants()) do
if part:IsA("BasePart") and part:GetAttribute("Hidden") then
table.insert(hiddenTiles, part)
end
end
RunService.RenderStepped:Connect(function()
if not VRService.VREnabled then return end
local handCFrame = camera.CFrame * VRService:GetUserCFrame(Enum.UserCFrame.RightHand)
local handPos = handCFrame.Position
for _, tile in ipairs(hiddenTiles) do
local near = (tile.Position - handPos).Magnitude <= REVEAL_RANGE
local target = near and 0 or FAINT
tile.Transparency = tile.Transparency + (target - tile.Transparency) * 0.2
end
end)
Lines 1–2Two tunable numbers.
REVEAL_RANGE is how near your hand must pass to light a tile. FAINT is the resting transparency — keep it equal to the 0.7 you set in Studio so tiles settle back to the same ghostliness.
Lines 4–9Scan for Hidden, not Killer.
We collect only tiles tagged Hidden. That keeps the reveal focused on this field instead of also lighting up Stage 4's kill bricks. Same scan shape as before, pointed at a different tag.
Lines 13–14Where is the hand in the world?
Exactly the Stage 1 climb math: the camera CFrame times the hand's VR offset gives the hand's real-world spot, so we can measure its distance to each tile.
Lines 16–20Light the near ones, fade the rest.
For each tile, if the hand is within range the target is 0 (solid); otherwise FAINT. The ease line slides each tile's transparency a fifth of the way toward its target every frame, so tiles glow on and fade off smoothly as your hand sweeps past.
Understand it
The deadly half of this stage is the reuse lesson made real. You created a brand-new kind of hazard and wrote zero lines to make it deadly — because Stage 4's Killer scan was built to handle any tagged part. This is why programmers obsess over patterns: a good one turns "build a new feature" into "tick a box." The bounce pad made the same point — it's literally your jump pad again.
The reveal wave is the recombination lesson. Look at what it's made of: a Hidden-attribute scan (you've done attribute scans since Stage 1), the hand-to-world position (Stage 1's climb), and the smooth ease (Stage 5's fade). Not one new structure — yet the result is a mechanic that exists in almost no other game. That's how real game features get built: not from exotic new code, but from familiar pieces snapped together in a fresh shape.
We kept the tiles faintly visible (0.7) instead of fully invisible so a laptop player still has a fair chance. The VR reveal isn't required to win — it's a power, an advantage your hands give you. Good VR design adds delight without locking out the people who don't have a headset.
Try this
Try this
Three short experiments. Predict before you run, then test your guess.
REVEAL_RANGE is 8. Predict how the reveal feels at 2 (tiny) versus 25 (huge). One makes you trace each tile precisely; one lights the whole field at once. Which is more fun to play — and why might "too helpful" be a worse game than "just helpful enough"?
The tiles rest at FAINT = 0.7. Try 0.95 (almost invisible) and 0.4 (clearly visible). With 0.4, does the reveal wave still feel worth using? What does that tell you about how a power's value depends on how hard the base challenge is?
Your reveal wave finds parts by the Hidden tag. Stage 8 has a spinning arm you'll want to grab. What attribute might you put on that so a future script can find grabbable parts? You're building a habit: tag the thing, then scan for the tag.
Test your stage
- Press ▶ Play and step on a faint red tile — you die and respawn (no new kill code needed).
- Cross the field by weaving the safe lane; use a bounce pad to leap a tight cluster.
- Touch the Stage 7 pad, reset, and confirm you respawn there.
- Output is empty on a clean Play — no errors from the bounce pad or
VRController. - Confirm every hazard has both
KillerandHiddenattributes and Transparency0.7. - Design check. Is there a real safe path, or did a hazard sneak into the only route? Walk it yourself with hazards at 0 transparency to check it's possible, then set them back to 0.7. A field with no safe lane isn't hard — it's broken.
If it breaks
- The tiles don't kill me. They're missing the
Killerattribute, or the Stage 4KillBricksscript isn't in ServerScriptService, or you added tiles after pressing Play (the scan runs once at start). - The reveal lights up my Stage 4 kill bricks too. Those have
Killerbut notHidden. If they're lighting up, you scanned forKillerinstead ofHiddenin the reveal block — fix the attribute name. camerais red in VRController. The reveal reuses thelocal cameraline from Stage 1 — make sure it's still at the top of the file.- Tiles flash on and never fade off (in VR). Your
FAINTvalue doesn't match the tile's resting transparency, or the ease line is missing. They should settle back to 0.7. - Nothing reveals on my laptop. Expected — no headset means no hand to sweep, so the loop is skipped. Verified at the Stage 10 playtest.
This is the "it all comes together" stage. Make the reuse explicit and loud: when a camper ticks Killer and the tile kills with no new code, stop the room and name it — "you just added a feature by recombining, not rewriting." That realization is the whole point of the course's spiral design.
The most common real bug is a hazard accidentally blocking the only safe path. Use the design-check trick: temporarily set all hazards to Transparency 0, walk the lane to prove it's possible, then set them back to 0.7. Build the field solvable first, scary second.
As always: the reveal wave can't be felt on a laptop; the clean Play is the pass. If campers want to verify their reveal logic, have them temporarily drop the if not VRService.VREnabled then return end guard and use their mouse — but remind them to put it back.