The mechanics are solid. But right now it's a prototype — not a game.
🎮 Prototype vs. Complete Game
Prototype
Starts mid-race with no context
No clear win or lose condition
Can't restart without the editor
No way to know who built it
Fun to build — awkward to hand to someone
Complete Game
Opens to a menu that sets expectations
Has a clear win and lose condition
Player can restart, quit, or return to menu
Credits give attribution and closure
A stranger can pick it up and play it
📋 Minimum Requirements
For full credit, your completed Blade Racer must include all three of the following:
1. Main Menu REQUIRED
A title screen where the experience begins. At minimum: a Play button and a route to Credits.
2. Complete Game Loop REQUIRED
The player can start a race, play to a defined win or lose condition, then return to the menu. No dead ends — every state connects back.
3. Credits Screen REQUIRED
A screen (or overlay) that credits the developer(s), any third-party assets used, and the course and institution.
Everything else is bonus. Get all three working and connected before exploring extras.
🎨 Your Game, Your Way
The requirements define the what — not the how. These are design decisions you get to own:
What ends the race? — Crash limit, distance goal, timer, score threshold, or something else entirely?
What does winning look like? — High score? Finishing a track? Defeating a boss drone?
What's on your menu? — Settings? Difficulty select? A garage for pre-race upgrades?
How do your credits play out? — Static text? Scroll? A post-victory cinematic?
What extras do you want? — Sound, leaderboard, multiple tracks, pause menu?
There is no wrong answer here. Build the game you want to build — just make sure all three required systems are complete and connected.
🗂️ Setting Up Your MVP Scenes
Before wiring any navigation, get your scene list locked in. Every SceneManager.LoadScene() call depends on these names and indices being stable.
File → Build Settings → drag scenes into the list:
Index
Scene Name
Purpose
0
MainMenu
Always the first scene loaded on launch
1
GameScene
The race — your core gameplay
2
CreditsScene
Attribution and closure
3
DevTestScene
Your prototype scene — dev access only (covered next)
Name your scenes before you write any navigation code. Renaming a scene after you've referenced it in SceneManager.LoadScene("OldName") will silently break at runtime — Unity won't warn you until you try to load it.
🔬 Your Prototype Scene as a Dev Tool
You've spent the whole semester in your original scene — full bike, drones, pickups, streaming track. Don't delete it. Rename it and keep it as a developer shortcut.
Rename it: SampleScene → DevTestScene
Skips the menu entirely — drops you straight into gameplay
Ideal for testing mechanics, debugging states, and stress-testing the Object Pool without playing through a full loop
Lives outside the normal player flow — never reachable from the Play button
Add a Dev Mode button to your Main Menu:
// In MainMenuManager — wire to a button labeled "Dev Mode" or hide itpublic voidOnDevModeClicked()
{
SceneManager.LoadScene("DevTestScene");
}
Pro habit: Keep the Dev Mode button visible while you're building. Once the game is complete and ready to submit, you can hide or remove it — but having it available throughout saves you from playing through menus hundreds of times during development.
🖥️ Step 1: Building Your Main Menu
What you need:
A dedicated Menu scene set as scene index 0 in Build Settings
A Canvas with your game title and navigation buttons
At minimum: Play and Credits buttons
using UnityEngine.SceneManagement;
public classMainMenuManager : MonoBehaviour
{
public voidOnPlayClicked()
{
SceneManager.LoadScene("GameScene");
}
public voidOnCreditsClicked()
{
SceneManager.LoadScene("CreditsScene");
}
public voidOnQuitClicked()
{
Application.Quit();
}
}
Keep it clean. A readable menu with clear buttons beats a flashy one that confuses players. Style it after you finish wiring everything up.
🔄 Step 2: The Game Loop
A complete game loop moves through defined states:
Menu → Countdown / Start → Gameplay → Game Over or Victory → Restart or Menu
Choose how the game ends — or invent your own:
Crash Limit — Three crashes = game over
Distance Goal — Survive a set track length to win
Timer — How long can you last? (survival mode)
Score Threshold — Reach a target to advance or win
Decide your end condition before you write any code. It determines what your GameManager needs to track and what events need to fire.
🗂️ Game State with GameManager
Your existing GameManager Singleton is the natural place to own overall game state — a straightforward extension of what you already built:
public enumGameState
{
Menu, Countdown, Playing, GameOver, Victory
}
public classGameManager : Singleton<GameManager>
{
public GameState CurrentState { get; private set; }
public voidSetState(GameState newState)
{
CurrentState = newState;
EventBus.Publish("GameStateChanged", newState);
}
public voidStartGame() => SetState(GameState.Playing);
public voidTriggerGameOver() => SetState(GameState.GameOver);
public voidTriggerVictory() => SetState(GameState.Victory);
}
Pattern in Action: The Event Bus broadcasts state changes — your HUD, audio manager, and UI panels all respond without the GameManager ever knowing they exist.
💥 Game Over & Win Screens
Two solid approaches — pick what fits your design:
Option A: Separate Scenes
Clean and easy — each outcome is its own scene
Load your Game Over or Victory scene when state changes
Each scene has a Restart button and a Return to Menu button
Option B: Canvas Overlay
More seamless — the race world stays visible behind the panel
Subscribe to the GameStateChanged event via Event Bus
Toggle panel visibility when state hits GameOver or Victory
// Game Over panel subscribing via the Event BusvoidOnEnable()
{
EventBus.Subscribe("GameStateChanged", OnStateChanged);
}
voidOnStateChanged(object state)
{
gameOverPanel.SetActive((GameState)state == GameState.GameOver);
victoryPanel.SetActive((GameState)state == GameState.Victory);
}
🎬 Step 3: Credits Screen
Your credits must include:
Your name (and any collaborators)
Course: CSCI 3213 — Game Programming, OCU, Spring 2026
Any third-party assets used (art, music, fonts, sound effects)
Implementation options:
Static Scene — A Canvas with text and a Back to Menu button. Simple and reliable.
Scrolling Text — Animate a TextMeshPro element upward with a Coroutine
Post-Victory Sequence — Credits roll after a win cinematic or ending card
You don't need to invent new architecture — what you built is designed for exactly this:
Feature
Pattern(s) You Already Have
Game state flow (menu → play → game over)
GameManager Singleton + Event Bus
UI reacting to player death or victory
Event Bus ("GameStateChanged" event)
Pausing without breaking the Object Pool
State Pattern + Time.timeScale = 0
Restart without memory leaks or ghost objects
Object Pool (reset and reuse, don't Destroy)
Live score updates to the HUD
Observer Pattern or Event Bus
Difficulty-scaled enemy AI
Strategy Pattern (swap drone behavior at runtime)
The patterns you studied aren't just for Blade Racer's mechanics — they're how professional games are structured end to end.
💡 Ideas to Take It Further
Once your three required systems are complete and connected, here are directions worth exploring:
Score SystemBONUS — Track distance, destroyed drones, pickups. Display on HUD and Game Over screen.
Pause MenuBONUS — Press Escape to pause with resume / return to menu. (Time.timeScale = 0)
Sound & MusicBONUS — Engine hum, crash sounds, weapon fire. A looping music track for the menu.
High ScoreBONUS — Persist the best run between sessions using PlayerPrefs.
Difficulty SettingsBONUS — Adjust drone spawn rate and speed from the menu before the race.
Visual PolishBONUS — Screen shake on crash, particle burst on drone kill, speed lines at high velocity.
Scope carefully. One polished bonus feature beats three half-finished ones. Finish the loop first.
💻 Workshop: Build Time
Recommended order of attack:
Set up your scenes in Build Settings — Create MainMenu, GameScene, CreditsScene, and rename your prototype to DevTestScene. Lock in names before writing any navigation code.
Decide your end condition — Crash limit? Distance? Score? Write it down before touching code.
Build the Main Menu scene — Title, Play, Credits, and Dev Mode buttons. Wire up SceneManager.LoadScene.
Extend GameManager with game state — Add the GameState enum and SetState(). Connect your crash/win detection to it.
Add Game Over and Win screens — Show the result. Offer Restart and Return to Menu on both.
Build the Credits scene or overlay — Simple is fine. Make sure it navigates back to the menu.
Test the full loop from a cold start — Menu → play → game over → restart → game over → menu → credits → menu. Every path must close.
📝 Grading & Deliverables
Submitted via GitHub — your final commit must include:
Required for Full Credit:
✅ Main Menu scene with Play button and Credits navigation
✅ A clearly defined win condition and a clearly defined lose condition
✅ Game Over and Victory screens with Restart and Return to Menu options
✅ Credits screen with your name, course info, and asset attribution
✅ Full loop playable: menu → race → outcome → menu
✅ No dead ends — every scene and state can return to the menu
Test it like a first-time player would. Launch the build, go through every path, and make sure nothing gets stuck or crashes. Then commit.
🏁 Let's Finish the Race
What we're building today:
✅ Main Menu — the front door of your game
✅ Complete Game Loop — players know how it starts, plays, and ends
✅ Credits — attribution and closure
Keep in mind:
The design decisions are yours — own them
Your patterns are already built — use them
Simple and complete beats complex and broken
Test the full loop from a cold start before you submit
You built a game engine. Now let's build a game. 🚀