Glyntfall's concept phase ended with a Conditional Go. Not a green light. A yellow one.
The concept was validated: clear audience, proven mechanics, exploitable competitive gaps, feasible architecture. But the entire game hinges on one subjective question that no document can answer. Does the destruction feel satisfying?
Sprint 2 was built to answer that question. One gate sprint. Pass it, and the project is real. Fail it, and the concept needs rethinking before another line of production code gets written.
What "Gate" Means in Practice
A gate sprint isn't a normal sprint. Normal sprints have stories, acceptance criteria, and a demo scenario. A gate sprint has all of those plus a binary outcome: the project continues or it doesn't.
The concept phase defined two conditions for the gate:
- Visual Target Build passes the feel test. Crystal shattering with the full juice stack (Voronoi fracture, bloom, shader effects) feels satisfying. Someone watching over your shoulder says "that looks cool."
- Physics confirms 60fps under peak load. Five simultaneous shatters with fragments, orbs, and effects running together don't tank performance.
The spikes had already validated the individual systems. The crystal shader works. Voronoi fracture works. Physics handles 10x our budget. But systems working in isolation don't prove they compose into something that feels good. Sprint 2 was the integration test.
Two Stories, One Session
Sprint 2 had two stories:
E3-S1: Voronoi Crystal Shattering. Wire the fracture system from the spike into the real game architecture. ShatterManager listens to ShatterEvent, orchestrates fracture and fragment spawning from an object pool. Fragments inherit the parent crystal's shader and color. Physics impulse from impact point. Fade and despawn.
E3-S2: Crystal Shader and Visual Identity. Apply the production crystal shader (tuned values from the spike) to actual game crystals. Create a reduced-cost fragment shader variant. Dark atmospheric background. URP Global Volume with Bloom.
The implementation order mattered. I'd been doing backend-first through the whole project (data layer, then service layer, then tests, then view/scene wiring) and it continued to pay off here. All the pure logic code and tests came first. Scene wiring came last.
The new code:
- ShatterPayload got ImpactPoint and CrystalColor fields so the fracture system knows where the orb hit and what color the fragments should be
- FragmentLifecycle (pure C#, no MonoBehaviour) handles fade timing and alpha calculations. Nine tests, all Edit Mode.
- FragmentController applies physics impulse, drives the fade-out via MaterialPropertyBlock, and returns fragments to the pool when done
- ShatterManager orchestrates the whole sequence: listens for ShatterEvent, calls VoronoiFracture to generate geometry, spawns fragments from the pool, applies impulse
- FragmentPool using Unity's ObjectPool<T>, prewarmed in ShatterManager.Awake so no allocation happens during gameplay
30 new Edit Mode tests. 121 total (up from 91 after Sprint 1). Zero failures.
The Moment It Worked
Scene wiring was the last step. Sprint2Setup.cs (an editor script following the pattern from Sprint 1) created the materials, built the fragment prefab, wired all the serialized references in the Game scene.
Hit Play. Tapped a crystal. It shattered.
The fragments flew outward with the crystal shader still active on each piece. Cyan fragments glowing cyan. Magenta fragments glowing magenta. Bloom catching the emission as pieces tumbled. Physics giving them weight, not floatiness. Alpha fading smoothly to zero. Pool reclaiming them silently.
Five simultaneous shatters. 60fps. No frame drops.
That was the gate. It passed.
What Made It Work on the First Try
"First try" is misleading. Sprint 2 was one session, but it was standing on a foundation of work that de-risked every component:
| What Worked | Why It Worked |
|---|---|
| Voronoi fracture integration | Spike 2 proved runtime generation at 0.36ms. No surprises in production. |
| Crystal shader on fragments | Spike 1's MaterialPropertyBlock approach meant fragments inherit color with zero allocation. |
| Physics performance | Spike 3 showed 10x headroom. 30 fragments from 5 shatters is trivial. |
| Object pooling | Sprint 0 scaffolded ObjectPool<T> as a foundation component. Pool was ready to use. |
| Event-driven architecture | ShatterEvent channel from Sprint 0. ShatterManager just subscribes. No coupling. |
Every piece had been validated independently. Sprint 2's job was assembly, not invention. That's what pre-production is supposed to buy you: sprints where the hard problems are already solved and you're wiring together proven components.
The One Thing That Didn't Work
The Play Mode tests. 4 of 5 OrbFiringTests have a pre-existing setup bug where OrbManager.Awake fires before the test's reflection wiring completes. This is a test infrastructure issue from Sprint 1, not a Sprint 2 problem. The actual game code works fine. But leaving broken tests in the suite bothers me.
Edit Mode tests (121 of them) all pass. The architecture's investment in pure logic classes (no MonoBehaviour dependency) continues to pay off. FragmentLifecycle, VoronoiFracture, FragmentMeshBuilder, FormationBuilder. All testable without Play Mode, all testable without a scene.
From Conditional Go to Full Go
The concept phase's Conditional Go had two conditions. Both are now resolved:
| Condition | Result | Evidence |
|---|---|---|
| Visual Target Build passes feel test | Pass | Crystal shattering with shader + bloom + physics feels satisfying. Fragments inherit glow and color seamlessly. |
| Physics confirms 60fps under peak load | Pass | 5 simultaneous shatters at 60fps. Spike showed 10x headroom. |
Conditional Go becomes Full Go. The project is real.
What This Means for Sprint 3
With the gate passed, Sprint 3 shifts to the game loop. WaveManager, RunManager, ScoreManager, ComboTracker, upgrades, HUD, main menu. The systems that turn a satisfying shatter interaction into an actual game.
The destruction feels right. Now it needs a reason to exist.
Noting What's Next for the Journal
Two more Glyntfall entries are queued up after Sprint 3 and beyond:
- Sprint 3: Building a game loop in three sessions. Built the main menu wrong (inside the gameplay scene), had to rip it out and rebuild with proper scene architecture. UI Toolkit CSS variable quirks. The mistake and the fix.
- Sprint 1: When pre-production pays off. Zero technical surprises because Sprint 0 spikes eliminated all risk. The boring sprint that validates the methodology.
Those will come as the project progresses.