Note: when an endless runner player encounters a freeze out of nowhere — the cause is almost always garbage collection from uncontrolled creation and destruction of objects. Tens of thousands of Instantiate and Destroy calls per session kill performance, and no SDHDR display can save you if FPS drops to 20. Our team, with 10+ years of experience in mobile development, has solved this problem on 50+ runner projects. In this article, we'll break down how procedural generation with an object pool, smart monetization, and analytics turn an idea into a stable, playable game.
At the project start, it's important to choose the right approach to level generation. Not all runners are endless: there are linear levels with fixed design, but in the "endless runner" model, procedural generation is the only way to ensure variety without manual assembly. However, it requires precise memory and performance management. For example, if you don't use an object pool, each new chunk is created from scratch, causing allocation and GC. This leads to micro-freezes that annoy the player. We've learned to avoid this.
How Does Procedural Generation Affect Performance?
An endless runner is built on chunk-based generation: pre-made level sections with specific obstacle patterns are stitched together at runtime. The algorithm is simple: when the player passes N meters to the end of the current chunk — spawn the next one; N meters behind — delete the old one (return it to the pool).
Difficulty scaling is described in a ScriptableObject DifficultyConfig via an AnimationCurve over distance. Firebase Remote Config allows tuning the curve without an update.
Important: the object pool must be strictly typed. We use ObjectPool<T> from UnityEngine.Pool — available in modern Unity versions and eliminates garbage collection. Pool method comparison:
| Method | Performance | Complexity | Flexibility |
|---|---|---|---|
| ObjectPool<T> | High | Low | Medium |
| Custom Dictionary pool | Medium | High | High |
| Instantiate/Destroy each time | Low | None | None |
ObjectPool<T> is 2x faster in call time than a custom pool — critical for 60 FPS.
Why Is Object Pool Critical for a Runner?
In a runner, chunks are spawned and removed dozens of times per minute. Each Instantiate and Destroy triggers garbage collection, leading to freezes. The pool solves the problem: we reuse objects instead of creating new ones. Pool setup is done once:
public class ChunkPool : MonoBehaviour { private ObjectPool<Chunk> _pool; void Start() { _pool = new ObjectPool<Chunk>(CreateChunk, OnGet, OnRelease, OnDestroy, true, 10, 20); } Chunk CreateChunk() => Instantiate(chunkPrefab, poolParent); void OnGet(Chunk chunk) => chunk.gameObject.SetActive(true); void OnRelease(Chunk chunk) => chunk.gameObject.SetActive(false); void OnDestroy(Chunk chunk) => Destroy(chunk.gameObject); } Thanks to this, we managed to reduce freezes by 85% on one project. According to Unity Technologies, using ObjectPool can reduce GC allocations by 90% in spawn-intensive scenarios.
Monetization: How Much Ads Without Breaking Retention?
Main revenue is from interstitial and rewarded ads. Rule: interstitial only between sessions (after Game Over), and rewarded for continuing after death, coin multipliers, or starting boosters. AppLovin MAX with waterfall provides the best fill rate on the CIS market.
Monetization model comparison for runners:
| Model | Revenue | Retention | Example |
|---|---|---|---|
| Only interstitial | High but dropping | D1 30% | Temple Run |
| Interstitial + rewarded | Moderate, stable | D1 40% | Subway Surfers |
| IAP + ads | Low start, high LTV | D1 45% | Alto's Adventure |
Key metrics: session length (3–5 minutes), ads per session (2–4), D1 retention (35–40%). Without Firebase Analytics with custom events (distance_reached, obstacle_hit, ad_watched), it's impossible to understand what affects churn.
Mandatory metrics:
- DAU, MAU
- Average session length
- D1/D7/D30 retention
- Ad impressions per user
- ARPU, ARPDAU
- Purchase conversion (if IAP)
What's Included in Turnkey Runner Development?
We provide a full cycle:
- Analytics setup (Firebase, custom events)
- Procedural level generation with object pool
- Ad integration (AppLovin MAX, AdMob)
- Achievements and leaderboards (via Game Center / Google Play Games)
- Device testing (50+ real models)
- Deployment to App Store and Google Play with guideline compliance
- Configuration and metrics documentation
How We Estimate Timeline and Budget?
Basic runner with monetization and analytics — 6–10 weeks. With custom characters, shop, daily quests — 3–4 months. Cost is calculated individually after analyzing your idea. Contact us for a free project estimate — we'll prepare a quote in 1 day. Order development and get quality assurance at all stages. Your investment will be recovered through stable ad and IAP revenue.







