Mobile RPG Game Development
RPG is the most voluminous genre in terms of interconnected systems. Inventory, quests, dialogues, leveling, combat system, world map, save/load—all must work cohesively without creating contradictory states. This is where "works in prototype, breaks in production" happens most often.
State consistency problem
Take a typical scenario: player accepted quest "kill 10 wolves," killed 8, closed game, it crashed during save. Quest counter reset to 0, but quest acceptance remains in dialogue history. On next launch, NPC offers quest again but shows "quest already accepted" condition. This is classic state inconsistency, abundant in RPG.
Solution: Event Sourcing for game progress. Instead of storing current state (questKillCount: 8), store event journal: [QuestAccepted(questId=12), WolfKilled, WolfKilled, ...]. Current state always reconstructs by replaying events. On crash, only events after last successful flush are lost—not entire save.
In Unity, implement via IGameEvent interface and EventStore with serialization to local SQLite (via SQLite-net-pcl package). Flush on every important event + background flush every 30 seconds via Coroutine or UniTask.
Dialogue system and narrative
Storing dialogues in ScriptableObject works for 50 lines. At 5000 lines of dialogue with branching—you need dedicated system. Options:
Ink (Inkle Studios) — open language for narrative games, compiles to JSON, runtime library for Unity (ink-unity-integration). Supports branching, state variables, conditions. Narrative designer writes in Inky editor, developer integrates finished script.
Yarn Spinner — alternative, more Unity-native, with visual node editor directly in Unity Editor. More convenient for small teams where designer works inside Unity.
Both support localization: strings extracted to CSV/XLIFF, translator works with tables, not scripts.
Inventory and items: architectural decisions
Inventory—place where "clever" solutions create problems. Typical mistake: create BaseItem class and inherit Sword, Potion, QuestItem. After 6 months PoisonedQuestSword appears and hierarchy breaks.
Correct approach: Composition over Inheritance via components or Data-Driven design. Each item is set of data-components: DamageComponent, ConsumableComponent, QuestMarkerComponent. System processes components independently. Adding new item type means adding new component, not touching existing code.
ScriptableObject as ItemDefinition (static data: name, icon, base stats) + runtime ItemInstance (dynamic data: modifiers, durability, custom name). So you can have 500 item types in memory as SO references and only actual instances in inventory as objects.
Combat system and turn-based mechanics
For step-by-step RPG: State Machine on each combat participant (PlayerIdle → PlayerSelectAction → EnemyTurn → AnimatingResult → ...) via Command pattern for combat actions. Each action is ICombatAction object with Execute() and Undo() methods. Undo() needed not just for "cancel turn," but for correct animation interruption handling.
For action-RPG: see architectural solutions from hardcore games section: ECS for simulation, MonoBehaviour for presentation.
Cloud saves
iOS: CloudKit via native plugin or Game Center (iCloud saves). Android: Google Play Saved Games (snapshots API). Must implement conflict resolution: if player played offline on two devices, need merge strategy (by timestamp or by progress).
Cost and timeline depend on scope: light RPG with linear story—6–10 months, open world with multiple classes, crafting, multiplayer—14–24 months. First stage always: designing data structure and save schema. Reworking this mid-development is expensive.
Development tools that save time
- Odin Inspector — custom editors for balance stat tuning directly in Unity Inspector without writing Editor code
- UniTask — async/await without GC allocations in Unity, critical for chapter and dialogue loading without freezes
- Addressables + Remote Content Delivery — content patching without app update
- Firebase Crashlytics — crash symbolization with C++ stack traces (IL2CPP)
- Unity Test Framework — PlayMode tests for combat system and save/load logic







