u/iOSHades

[DEV] I am a solo developer building a guild master management RPG. Here is how it looks after 6 months of updates.

Hi everyone. I wanted to share some progress on my project, Adventurers Guild. I have been working on this for about a year as a solo developer, and the game has been live for six months now.

The core concept is that you play as the master of a new guild rather than the heroes themselves. You recruit adventurers, manage their skill trees, and assign them to solo or group hunts. Once they head out, the combat is automated and driven by their individual personality traits. For example, some heroes will prioritize supporting their teammates during a group hunt, while others focus entirely on the monster. Right now there are 40 different spider enemies to hunt, so your heroes will face a lot of variety in combat.

They also manage their own physical limits. If a hero becomes too fatigued, they will choose to stop the hunt and return to the inn to rest.

As the guild master, you manage their loot and equipment. There are over 100 different pieces of equipment you can collect for your heroes. You can repair their gear or combine items to forge higher tier weapons for them to use. You also work on building up the guild hall itself. Upgrading the hall is how you unlock new facilities like the blacksmith or the potion shop to support your team.

I have also put a lot of work into the atmosphere of the world. The game features a dynamic day and night cycle and a weather system where rain actually interacts with the ambient lighting.

The game is currently about half complete, and I am still actively adding new systems. I attached a short video showing the weather transitions and some combat. I would love to hear what you think about the management loop and the overall visual style.

The game is a 38MB download size, (51MB after install) that runs completely offline with zero ads, all powered by a custom engine I built from scratch in Kotlin over the last year. I am putting all revenue back into the game as I finish the remaining 50% of the game

If you want to try it out and build your own guild, here is the link to the game.

https://play.google.com/store/apps/details?id=com.vimal.dungeonbuilder&pcampaignid=web_share

u/iOSHades — 7 days ago
▲ 66 r/Kotlin+1 crossposts

I built a performant Isometric Game Engine using 100% Pure Kotlin and Compose

About 5 months ago, I shared a technical experiment here. I was building an isometric RPG called Adventurers Guild using Pure Kotlin and Jetpack Compose instead of a traditional game engine. Back then, I was testing a custom coroutine loop and viewport culling to hold 60fps with 3000 entities on a Canvas.

Since that post, the game has crossed 4000 downloads. This custom Kotlin engine was recently shortlisted for the JetBrains Golden Kodee Community Award for Creativity. While I did not make it to the final round, getting that recognition from the Kotlin community as a solo developer was a significant milestone.

Writing a game engine natively in Kotlin means you have to fiercely protect the frame budget and minimize Garbage Collection pauses. I wanted to share the technical solutions I used to keep the Kotlin game loop smooth while scaling the simulation to handle a massive item database and complex AI.

1. The Coroutine Game Loop and Task Amortization The engine is single threaded and driven by a Coroutine loop using withFrameMillis to calculate delta time. The engine currently ticks over 28 distinct systems, handling everything from A Star Pathfinding to the Combat Pipeline.

Running 28 systems over thousands of entities every single frame is a recipe for GC churn and frame drops. To fix this, I implemented a tiered System Manager. Logic is categorized by its necessity for visual fluidity:

  • Fast Systems (60 FPS): Essential movement and frame by frame Canvas rendering.
  • Medium Systems (30 FPS): Combat calculations, damage application, and status effect updates.
  • Slow Systems (10 FPS): Heavy background tasks like A Star pathfinding and target selection AI.

Slicing these tasks over different frames prevents the Kotlin logic calculations from blocking the Compose composition phase.

2. Idiomatic ECS and State Mapping Managing game state in Compose requires bridging raw ECS data to stable UI states. Entities are simple IDs, and Components are raw Kotlin data classes. The systems iterate over these components to mutate state. Connecting this high frequency ECS to the Compose UI relies on a Mapper pattern. Every frame, the engine maps the relevant raw Components into a stable UiModel. Relying on MutableMap for O(1) time complexity lookups has been critical to prevent the main thread from choking when updating multiple entities at once.

3. The Optimization Triangle: CPU vs RAM vs GPU The biggest lesson over the last 5 months was managing the trade offs between hardware resources:

  • Trading RAM for GPU Processing: I added 40 new monster variants. To avoid loading 40 unique sprite sheets, I used Compose ColorFilter techniques. For monsters with high detail, I load a single base asset and mathematically rotate the hue using a ColorMatrix at runtime. Because these operations are hardware accelerated, the math is offloaded to the GPU. This cut RAM usage by 50 percent while keeping the CPU free.
  • Trading CPU for RAM (Caching): Dynamic shadows change angle and length based on the in game time. Instead of calculating this geometry every frame, the engine pre calculates the shadow states for the day and caches them. I spend a small amount of RAM to buy back crucial CPU frame time.

4. Micro Optimizations in the Hot Path When writing systems that execute thousands of times a second in Kotlin, you have to respect CPU clock cycles. I learned that operations like addition and multiplication are significantly faster for a CPU to process than division or calculating square roots. To optimize the hot path, I removed division where possible, opting to multiply by fractions instead. I also rely strictly on squared distance comparisons to avoid expensive square root calculations in the pathfinding logic.

5. Expanding the RPG Logic The simulation has scaled heavily since the initial experiment:

  • Hero Classes: Heroes have specific classes that alter their base stats, scaling performance based on equipped gear.
  • Personality AI: Heroes carry flags that alter their ECS logic. Careful heroes query the health of teammates and prioritize support over loot, while Reckless heroes ignore teammate health and stay in a combat state until the mob is cleared.

Building this engine and expanding the game from scratch has been a massive learning experience. Seeing the performance hold up on older devices makes the effort worth it.

I am happy to answer any questions about writing game loops with Coroutines, managing ECS state in Compose, or the DrawScope art workflow.

If you are curious to see how this custom Kotlin engine handles these 28 systems in production, you can check it out on the Play Store: Adventurers Guild

I am a solo dev from Kerala. Hope this technical breakdown was helpful.

play.google.com
u/iOSHades — 7 days ago
▲ 64 r/rpg_gamers+3 crossposts

5 Months Later: Scaling a 100 percent Jetpack Compose RPG Engine (Grayscale Hue Shifting, Tiered ECS, and 50 percent RAM Reduction)

About 5 months ago, I shared the Version 1 release of Adventurers Guild. For those who missed the original post, it is an isometric RPG built entirely 100 percent Kotlin and Jetpack Compose. The visual layer is drawn directly onto a Compose Canvas, and the underlying logic runs on a custom Entity Component System (ECS).

Since then, the game has crossed 4000 downloads and the engine was shortlisted for the Golden Kodee Community Award for Creativity. While I did not make it to the final round, getting that recognition from JetBrains as a solo developer building an engine from scratch was a significant milestone.

Running a game natively in Android means fiercely protecting the 16ms frame budget of the Main Thread. Rewriting the engine for full multithreading is a massive future undertaking, so the engine currently operates on a single thread. I wanted to share the technical solutions I used to keep the Compose UI smooth while scaling the simulation.

1. Frequency Tiered Systems The engine currently ticks over 28 distinct systems. These handle everything from A* Pathfinding and Monster AI to the Combat Pipeline, Weather Generation, and Economy.

In traditional game development, it is common to run every system every frame. In a native Android environment, doing this with 28 systems causes immediate thermal throttling and frame drops. To fix this, I moved away from a brute force game loop to a tiered System Manager. Logic is now categorized by its necessity for visual fluidity.

  • Fast Systems (60 FPS): Essential movement and frame by frame Canvas rendering.
  • Medium Systems (30 FPS): Combat calculations, damage application, and status effect updates.
  • Slow Systems (10 FPS): Heavy background tasks like A* pathfinding and target selection AI.

The player cannot perceive a delay in a monster choosing a target 10 times a second versus 60 times a second, but the CPU relief is massive. This prevents the logic calculations from blocking the layout and draw phases of Compose.

2. Memory Optimization: Tinting and Hue Rotation I recently added 40 new monster variants. To keep the APK small and prevent RAM bloat on older devices, I avoided loading 40 unique sprite sheets. Instead, I used two distinct ColorFilter techniques on the Compose Canvas.

  • Grayscale to Tint: For simpler entities, I load a single grayscale base sheet and apply a solid color tint at runtime.
  • Hue Rotation: For monsters with more detail, I load a base colored asset and mathematically rotate the hue at runtime. This preserves the original highlights and shadows while allowing for a complete color shift. It feels like a different species of the monster with the same level of detail as the base.

These dynamic canvas filters, combined with smart asset unloading, resulted in a 50 percent reduction in RAM usage and a 40 percent smaller game size.

3. Atmospheric Systems on Canvas Building an immersive world in Compose meant handling environmental effects without a dedicated particle engine. I built several systems that draw directly onto the Canvas DrawScope.

  • Day and Night Cycle: A global overlay that shifts color and alpha based on the clock in the game.
  • Weather System: A procedural rain system and dynamic fireflies that use simple math to update their positions and fade in and out every frame.

4. Expanding the RPG Logic The simulation has scaled heavily since launch to include new RPG mechanics.

  • Hero Classes: Heroes now have specific classes that alter their base stats, scaling their performance differently depending on the gear equipped.
  • Personality AI: To make the new Group Hunt mode feel organic, heroes carry Personality flags that alter their ECS logic. Careful heroes constantly query the health of teammates and prioritize support over loot, while Reckless heroes ignore teammate health and stay locked in a combat state until the mob is cleared.

5. The Optimization Triangle (CPU vs RAM vs GPU) The biggest lesson over the last 5 months was realizing that optimization is just a constant negotiation between the CPU, RAM, and GPU.

  • Trading RAM for GPU: As mentioned with the hue shifting, avoiding 40 unique sprite sheets saved massive amounts of RAM. Because ColorFilter operations in the Compose DrawScope are hardware accelerated, the math to shift those hues is offloaded directly to the GPU. We essentially traded a bit of GPU processing power to get that 50 percent RAM reduction.
  • Trading CPU for RAM: Conversely, there are places where the CPU needs relief. Because dynamic shadows change angle and length based on the in game time of day, calculating that isometric geometry every frame requires heavy math. Instead of doing this 60 times a second, the engine pre calculates the shadow states for the day and caches the results. We spend a tiny sliver of RAM to buy back crucial CPU frame time.

6. Micro Optimizations in the Game Loop When building systems that execute thousands of times a second, you have to respect CPU clock cycles at a micro level. I learned that operations like addition and multiplication are significantly faster for a CPU to process than division or calculating square roots. To optimize the engine, I completely removed division where possible, opting to multiply by fractions instead, and I rely on squared distance comparisons to avoid expensive square root calculations in the pathfinding logic.

Building this engine and expanding the game from scratch has been a massive learning experience. Seeing the performance hold up on older devices makes the late night coding sessions worth the effort.

I am happy to answer any questions about the Compose Canvas pipeline, single thread ECS optimization, or the grayscale art workflow.

If you are curious to see how this custom Jetpack Compose engine handles these 28 systems and 4000+ items in production, you can check it out on the Play Store: Adventurers Guild

https://play.google.com/store/apps/details?id=com.vimal.dungeonbuilder&pcampaignid=web_share

youtu.be
u/iOSHades — 7 days ago