Trigger core loop events from world movement. Connect space to risk.
Every RPG has moments where you're just walking along and suddenly — BAM — a wild encounter appears. But how does the game decide when? Watch this video to see how game designers use randomness to create surprise and tension:
The Two Types of Random in Game Design — GMTK
Mark Brown explores how randomness works in games — from random encounters to loot drops to procedural generation. You'll see why some randomness feels fair and some feels cheap.
Discussion after watching: Think about your favorite RPG or adventure game. When you walk around and an encounter suddenly fires, does it feel random or does it feel like the game chose the right moment? What if encounters happened every 3 seconds vs every 3 minutes — how would that change the feeling?
Location + Probability = Event. Now we connect the zones from last week to game events. Being in a dangerous area creates a chance of something happening. The world is no longer passive — it reacts to where the player is standing.
You need: A standard deck of playing cards (or make a mini-deck with index cards labeled RED and BLACK).
Setup: Start with a deck of 10 cards: 2 red cards and 8 black cards.
Rules:
- Shuffle the deck face down.
- Flip one card at a time. Black card = nothing happens, keep walking. Red card = ENCOUNTER! Write it down.
- Go through all 10 cards. Count how many encounters happened out of 10 flips.
- Now change the ratio: make it 4 red, 6 black. Shuffle and flip again. How does the encounter rate change?
- Try 7 red, 3 black. What happens now?
Record your results:
| Deck Mix | Red Cards | Encounters / 10 | Encounter Rate | How did it feel? |
|---|---|---|---|---|
| Low danger | 2 / 10 | ~20% | ||
| Medium danger | 4 / 10 | ~40% | ||
| High danger | 7 / 10 | ~70% |
This IS Math.random(). In your code, Math.random() < 0.2 is the same as having 2 red cards in a deck of 10. When your game says Math.random() < 0.01 * riskLevel, you're changing the ratio of red cards in the deck. Higher riskLevel = more red cards = more encounters. You just played your own probability engine with physical cards.
When the player is in the Manhattan (danger) zone, there is a small percentage chance per second to trigger an encounter. The higher the risk level, the more likely an encounter fires. For now, an encounter is just a console message — no UI yet.
When standing on a buildable lot, the player can press "E" to accept a job. Each job appears with a cost (materials needed), a payout (karma earned), and a simulated time to complete. Jobs are the economic trigger — without accepting one, nothing happens.
The triggerEncounter() function creates an encounter and stores it in game state:
The createJob() function generates a job offer:
Store the active event in gameState:
Walking in the danger zone eventually triggers an encounter. Standing on a lot generates a job. Both events appear in the console.
No animations. No UI panels yet. Console output only.
Encounter triggering every frame — use a timer or cooldown so encounters don't fire 60 times per second.
Job generating without being on a lot — always check zone before creating a job.
Not clearing the previous event before creating a new one — check gameState.activeEvent before firing a new trigger.
The card activity is essential. Do not skip it. The physical act of flipping cards and watching encounter rates change is the "aha" moment that makes Math.random() intuitive rather than abstract. After the activity, point at the code and say: "See 0.01 * riskLevel? That's the same as changing how many red cards are in the deck."
This is where the world comes alive. The connection between space (Day 9-10) and events (today) is the core architectural insight. The player's position in the world now has consequences — that's what makes a game feel real. Ask: "Why must events be triggered by space? Why not just trigger them randomly with a timer?"
If kids finish early, have them experiment with different probability values in the console. What happens at 0.001? At 0.5? Let them feel the difference between "too rare" and "too frequent" before settling on their final number.
Tomorrow: We decide what happens when the encounter fires — the resolution engine. Right now your events trigger but have no consequence. Tomorrow, winning and losing will actually mean something.