Idle and tycoon games look almost deceptively calm from the outside. Numbers go up, a room upgrades, a manager gets hired, income compounds. There's no twitch reflex required, no combo timing, nothing that looks technically demanding in a screen recording. That surface simplicity is exactly why so many developers underestimate how much engineering sits underneath a well-built idle game.
Idle games live or die by a handful of systems that have almost nothing to do with visuals: offline progress calculation, exponential cost curves that stay balanced for weeks of play, save-data integrity, and UI that updates dozens of numeric values every frame without tanking performance on a mid-range phone. None of that shows up in a screenshot, but all of it determines whether players stick around past day three.
This article breaks down the core systems behind a hotel-management idle game specifically — using the My Perfect Hotel Idle Unity source code as the reference point — with working code examples so you know exactly what to check before buying a source code package in this genre, or what to build yourself if you're starting from scratch.
Why Idle/Tycoon Architecture Is Its Own Discipline
Idle games have a set of constraints that don't show up in most other mobile genres:
- Progress has to continue while the app is closed. Unlike almost every other genre, idle games are explicitly designed around the player not playing, which means offline-time calculation is a first-class system, not an afterthought.
- Numbers scale for a very long time. A hotel that starts earning a few coins per second needs to plausibly scale into the millions or billions over a play session that can stretch across weeks, which means cost and reward curves need careful mathematical design, not arbitrary multipliers.
- State needs to persist reliably. Losing a player's progress after three days of play is one of the fastest ways to tank retention and reviews in this genre specifically, since the entire value proposition is watching a number grow over time.
- UI updates constantly. Coin counters, per-second income displays, and progress bars often update every frame across dozens of rooms or floors simultaneously, so naive UI code can quietly become a performance bottleneck.
None of this is visible in a fifteen-second gameplay clip of a hotel lobby filling up with guests, but all of it needs to be solid before the game is actually enjoyable to leave running in the background.
System 1: Idle Income and Offline Progress Calculation
The core loop of any idle hotel game is generating income per second from owned rooms, staff, or amenities, and then correctly calculating how much was earned while the app was closed.
A clean implementation separates the rate calculation from the time elapsed calculation:
public class IncomeManager : MonoBehaviour
{
public List<HotelRoom> ownedRooms;
public double currentCoins;
public double GetIncomePerSecond()
{
double total = 0;
foreach (var room in ownedRooms)
{
total += room.baseIncome * room.level * room.multiplier;
}
return total;
}
public void ApplyOfflineProgress()
{
string lastSaveTime = PlayerPrefs.GetString("LastSaveTime", "");
if (string.IsNullOrEmpty(lastSaveTime)) return;
DateTime lastTime = DateTime.Parse(lastSaveTime, null, System.Globalization.DateTimeStyles.RoundtripKind);
double secondsElapsed = (DateTime.UtcNow - lastTime).TotalSeconds;
// Cap offline earnings to prevent absurd results from clock manipulation
double cappedSeconds = Math.Min(secondsElapsed, 8 * 3600); // 8 hour cap
double earned = GetIncomePerSecond() * cappedSeconds;
currentCoins += earned;
}
void OnApplicationPause(bool paused)
{
if (paused)
{
PlayerPrefs.SetString("LastSaveTime", DateTime.UtcNow.ToString("o"));
}
}
}
A few details here matter more than they look:
- Using
doubleinstead offloatfor currency values is not optional once numbers scale into the hundreds of thousands — float precision breaks down long before most players reach late-game income levels. - Capping the maximum offline duration prevents both clock-manipulation exploits and the awkward UX problem of a player returning after two weeks to find an absurd, meaningless coin count.
- Storing the timestamp on
OnApplicationPauserather than only on app quit matters on mobile, since Android and iOS frequently suspend apps without a clean quit event firing.
If you're evaluating a source code package in this genre, this is one of the first things worth checking: open the save/income scripts and confirm offline progress is actually implemented, capped sensibly, and using appropriately precise number types.
System 2: Scalable Upgrade and Cost Curves
The second core system is the cost curve for upgrading rooms, hiring staff, or unlocking new hotel floors. Get this wrong and the game either becomes trivially easy to max out in an hour, or so punishingly slow that players churn before reaching anything satisfying.
A standard exponential cost curve looks like this:
[System.Serializable]
public class UpgradeableAsset
{
public string assetName;
public int level;
public double baseCost;
public double costGrowthRate = 1.15; // 15% cost increase per level
public double baseIncome;
public double incomeGrowthRate = 1.10; // 10% income increase per level
public double GetUpgradeCost()
{
return baseCost * Math.Pow(costGrowthRate, level);
}
public double GetCurrentIncome()
{
return baseIncome * Math.Pow(incomeGrowthRate, level);
}
public bool TryUpgrade(ref double playerCoins)
{
double cost = GetUpgradeCost();
if (playerCoins < cost) return false;
playerCoins -= cost;
level++;
return true;
}
}
The relationship between costGrowthRate and incomeGrowthRate is the actual game design lever here. If cost grows faster than income, upgrades become progressively less efficient over time, which pushes players toward unlocking new rooms or floors instead of just re-investing in one asset — a deliberate pacing decision, not an accident. A well-built idle template should expose these growth rates as easily tunable values rather than burying them as magic numbers scattered across dozens of scripts.
System 3: Reliable Save Data and Anti-Corruption Handling
Because idle games are specifically designed around long, unattended play sessions, save-data reliability matters more here than in almost any other genre. A player who reopens the app to find their three-day hotel empire reset to zero is a player who uninstalls immediately.
A reasonably safe serialization pattern uses JSON with a lightweight integrity check:
[System.Serializable]
public class SaveData
{
public double coins;
public List<RoomSaveEntry> rooms;
public string lastSaveTimestamp;
}
public class SaveManager : MonoBehaviour
{
private string SavePath => Application.persistentDataPath + "/hotel_save.json";
public void Save(SaveData data)
{
data.lastSaveTimestamp = DateTime.UtcNow.ToString("o");
string json = JsonUtility.ToJson(data);
File.WriteAllText(SavePath, json);
// Keep one backup copy in case the primary write is interrupted
File.WriteAllText(SavePath + ".bak", json);
}
public SaveData Load()
{
try
{
if (File.Exists(SavePath))
{
string json = File.ReadAllText(SavePath);
return JsonUtility.FromJson<SaveData>(json);
}
}
catch
{
// Primary save is corrupted, attempt backup recovery
if (File.Exists(SavePath + ".bak"))
{
string backupJson = File.ReadAllText(SavePath + ".bak");
return JsonUtility.FromJson<SaveData>(backupJson);
}
}
return new SaveData { coins = 0, rooms = new List<RoomSaveEntry>() };
}
}
The backup-file pattern is a small addition that solves a real, recurring problem: a write interrupted by an app crash or a sudden device shutdown can leave a save file partially written and unreadable. Falling back to the previous backup copy instead of resetting the player to zero is a cheap safeguard that a lot of rushed idle-game codebases skip entirely.
System 4: Event-Driven UI Instead of Per-Frame Polling
Idle games display a lot of constantly changing numbers — total coins, income per second, per-room output, progress toward the next unlock. A naive implementation updates every UI text field in Update(), which works fine in a demo scene and then quietly becomes a performance problem once a hotel has thirty rooms each displaying their own live income figure.
A cleaner pattern uses events to update only what actually changed:
public class CurrencyController : MonoBehaviour
{
public static event Action<double> OnCoinsChanged;
private double coins;
public void AddCoins(double amount)
{
coins += amount;
OnCoinsChanged?.Invoke(coins);
}
}
public class CoinDisplay : MonoBehaviour
{
public TMP_Text coinText;
void OnEnable()
{
CurrencyController.OnCoinsChanged += UpdateDisplay;
}
void OnDisable()
{
CurrencyController.OnCoinsChanged -= UpdateDisplay;
}
void UpdateDisplay(double newAmount)
{
coinText.text = FormatNumber(newAmount);
}
string FormatNumber(double value)
{
if (value >= 1_000_000_000) return (value / 1_000_000_000).ToString("0.##") + "B";
if (value >= 1_000_000) return (value / 1_000_000).ToString("0.##") + "M";
if (value >= 1_000) return (value / 1_000).ToString("0.##") + "K";
return value.ToString("0");
}
}
Two things worth flagging here: first, the event-driven approach means a coin display only redraws when coins actually change, rather than every single frame regardless of whether anything updated. Second, the number-formatting helper is a small but essential detail specific to this genre — displaying "15,482,930,442" instead of "15.48B" is a fast way to make late-game numbers feel unreadable and overwhelming rather than satisfying.
System 5: What This Looks Like in a Complete, Shipped Package
Reading these systems individually is useful, but it's more instructive to see them working together inside a finished project. This is where looking at a complete package like the My Perfect Hotel Idle source code is worth the time, since it shows how income calculation, room-upgrade curves, offline-progress handling, and UI updates are wired together across an entire hotel-floor progression rather than in isolated code snippets. Studying how a shipped project organizes its save data structure, its room-unlock sequencing, and its currency-formatting layer tends to teach more about real-world idle game architecture than reading the individual patterns in the abstract.
If you want a broader framework for evaluating any Unity source code purchase, not just idle games specifically, this deeper technical breakdown of what actually makes a hyper-casual Unity source code worth buying covers the same category of architectural questions — separation of visuals from logic, object pooling, monetization wrapping, and build configuration — that apply just as much to a tycoon or idle project as they do to a single-mechanic hyper-casual loop.
System 6: Monetization Patterns Specific to Idle Games
Idle games monetize differently than most other mobile genres, and a good source code package should reflect that in its architecture:
- Rewarded video for income boosts — a 2x income multiplier for the next 30 minutes in exchange for watching an ad is one of the highest-performing rewarded placements in the genre, since it directly reinforces the core "watch the number grow" loop.
- Rewarded video for instant offline-earnings doubling — offering a "watch an ad to double your offline earnings" prompt on app reopen is a near-universal pattern in successful idle games, and it should be a pre-built hook rather than something you bolt on later.
- IAP for permanent multipliers or time skips — unlike hyper-casual games, idle games often support meaningful IAP beyond just ad removal, including permanent income multipliers or one-time "skip ahead" purchases.
Checking whether these hooks exist as clean, callable methods (similar to the AdManager wrapper pattern common in hyper-casual architecture) versus being entirely absent is a fast way to gauge how much monetization work is left for you to do after purchase.
Applying These Principles Beyond Hotel Management
The systems covered here — precise currency handling, exponential cost curves, resilient save data, and event-driven UI — aren't unique to hotel-themed idle games. They apply directly to any progression-driven genre where numbers need to scale believably over long play sessions, including idle games built around a different core fantasy entirely.
A good comparison point is a genre like idle tower defense, where the same underlying systems (currency scaling, offline progress, persistent upgrades) get combined with wave-based combat and unit placement. The Idle Kingdom Defense Unity game source code is a useful reference for seeing how these idle-economy fundamentals extend into a combat-driven structure, layering tower upgrades and wave progression on top of the same core income-and-persistence architecture discussed above. Comparing the two genres side by side is a good exercise for understanding which parts of idle-game architecture are universal, and which parts are specific to the particular fantasy — hotel management versus kingdom defense — you're building around.
A Practical Checklist Before You Buy
Pulling this together into something you can actually use when evaluating a listing:
- Open the currency and income scripts — is
doubleused for monetary values, orfloat/int, which will break down at scale? - Check for an offline-progress calculation — does it exist, and is there a sensible cap to prevent exploit or absurd results?
- Look at the upgrade-cost formulas — are growth rates exposed as tunable serialized values, or hardcoded magic numbers?
- Inspect the save system — is there any backup or corruption-recovery handling, or a single point of failure on one file write?
- Check the UI update pattern — is it event-driven, or is every numeric display being refreshed inside
Update()regardless of whether it changed? - Confirm whether rewarded-video hooks for income boosts and offline-earnings doubling already exist, since these are close to mandatory in a competitive idle game today.
Final Thoughts
Idle and tycoon games reward patience from players, but they demand precision from developers. The genre's entire appeal depends on numbers that feel meaningful and fair across days or weeks of play, on progress that survives app closures and device restarts without corruption, and on interfaces that stay responsive even as dozens of values update simultaneously. None of that complexity is visible in a hotel lobby screenshot, but all of it determines whether a player opens the app again tomorrow.
The patterns covered here — double-based currency, exponential but tunable cost curves, backup-protected save files, and event-driven UI — are neither exotic nor difficult to implement individually. What matters is whether a source code package has already gotten them right, tested them across a real play session, and structured them so you can tune the numbers without touching core logic. Check for those details before you buy, and you'll spend your time on room themes, hotel branding, and marketing — not on rebuilding the plumbing that makes an idle game actually feel good to leave running.

Top comments (0)