top of page

Kriyatus : Pseudo Open World Action-Adventure Mobile Game

Kriyatus is a 3D action adventure game built on Unity URP for mobile.

This was the last project I worked on, where I handled environment design, level design, some of the gameplay systems and, general code and shader optimisations for mobile. This blog post is going to be a mix of design and code architecture in random order.

The game is set on an alien world with red coloured foliage and a teal sky. You can check out the demo on the Google Play Store right now!

You can check out some gameplay footage here as well.

Unity features and packages used:

  1. Terrain Tools - Terrain Tools | Terrain Tools | 5.3.1

  2. Shader graph - Unity - Manual: Creating shaders with Shader Graph

  3. HLSL Shaders

  4. Timeline - Unity's Timeline | Timeline | 1.8.9

  5. Sequences - Sequences package | Sequences | 2.1.3

    1. Support for the Sequences package is scheduled to end as of Unity 6.1

  6. Cinemachine - Cinemachine

  7. Occlusion Culling - Unity - Manual: Occlusion culling

  8. Volumes for post processing effects - Unity - Manual: Volumes in URP

  9. Live Capture - Live Capture package | Live Capture | 4.0.0

A screenshot of the playstore page of kriyatus
1k+ downloads yayy!!

Summary


The first area is designed to teach the core mechanics such as climbing, attacking, and blocking. Right next to it is the second area, an enemy camp, where the player receives their first main objective: eliminate all the monsters in the camp to complete the quest.

The layout of the first area is built to teach these mechanics naturally. Enemies are placed in key spots to guide the player through each move and prepare them for the upcoming mission.

In the camp area, players can choose how they want to approach the fight. They can go in head-on or take the stealth route. The demo introduces crouching and hiding in bushes early on, which becomes essential here. You can sneak through bushes, observe enemy movement patterns, use the Clairvoyance ability (similar to eagle eye vision), and perform stealth takedowns.

If the player chooses to attack directly, they will need to make good use of the dodge and shield mechanics. The combat was made slightly challenging on purpose, encouraging players to think strategically when taking over the camp. There is also a vantage point overlooking the camp that players can use to plan their approach.


Gameplay systems

As I mentioned in the previous section, the level is targeted at two types of play style. The stealthy style or the "guns blazing all out" style. Let's take a look at how these two styles were facilitated in the level.


Enemies

There are 2 types of enemies, the short fast guy (minor enemy) who does quick damage but dies with 2 hits from the player's staff and the golem (major enemy) who does a lot of damage, but his attacks are slow. The alerter is a special golem who can alert some enemies nearby to the players location if the player is detected.

ree

Now this is a big messy screenshot. Let's break it down.

The yellow line is the hero's path for a stealthy approach, well at least one of the stealthy approaches.

The black lines represent an enemy's path.

The blue line represents the alerter enemy's path.

The blue squares represent bushes in which the player can hide from enemies.

The camp is divided into 2 parts, the northern part which is accessible by the portal or the path on the right.

There are 3 stealth approaches, the hero's path you see in the image above is one, the second variation is to deal with the first closest enemies closest to the vantage point and head north directly instead of dealing with the enemies in the bottom. The third variation is to deal with the enemies close to the vantage point and then go west and deal with the enemies there and go eastwards and then head up north.


Enemy patrolling behaviour

Now all of these approaches are present by design, by playtesting and tweaking the patrol position and timings of each enemy.

There are two parts to this.

Each enemy has a patrolling behaviour script which is part of a bigger state machine part of FS Melee Combat and Parkour system (Check it, cool stuff and absolutely brilliant developers - FS - Melee Combat System | Game Toolkits | Unity Asset Store , no this is not sponsored I just love their work.)

Now the way the enemy knows where to go is based on a list of empty gameobjects played in specific locations. Each of these gameobjects have a "Waypoint" script attached to them telling the enemy how long to wait at each point in the routine.

ree

Each green point represents a waypoint for the enemy to go to. For convenience the wait time is visible in the editor as a handle text. Each waypoint also has an ID, this was because I had implemented a system which would allow changing the wait time in runtime while testing and it would dump it into a file which can be read from another tool and set in the waypoints in the editor again. This made it easy to tweak the enemy behaviour as close to ideally possible.

Although it took a lot of time to get close, after a certain duration of gameplay the system would go out of sync eventually which was within permissible range to not worry about (Demo gameplay time is around 20 minutes).

Originally, I wanted the positions to be represented by handles, but settled with a simple gameobject approach because it was much simpler and the number of enemies were really less.
Originally, I wanted the positions to be represented by handles, but settled with a simple gameobject approach because it was much simpler and the number of enemies were really less.

Noise system

Along with the combat features from the FS Combat System, I implemented a noise+distance based detection system as well. What this meant is that if the player was to crouch and walk around, he'd not be detected as quickly as compared to if he was running, or if the player did something high profile like try attacking it would also alert the enemy. Each action that the player could do was mapped to a value and there was a simple method to check for distance falloff as well and the returned value from this distance falloff method would decide if the player would be detected or not. It also decided how quickly the player got detected as well.

Each enemy has a vision sensor script which is for detecting the player. The green sphere is the range in which the vision sensor works
Each enemy has a vision sensor script which is for detecting the player. The green sphere is the range in which the vision sensor works

Here's a small snippet of how this works

Location Manager

One of the most time-saving tools I have written LOL
One of the most time-saving tools I have written LOL

This is a simple editor tool that also has a runtime api for moving the player around to specific locations. The data is stored in a scriptableobject.

It allows for creating new locations as well as easily updating and removing locations. Has saved tonnes of time in testing.

There is also an in-scene gizmo that shows up for each of the locations.

In scene gizmo for a location that is stored in the location manager
In scene gizmo for a location that is stored in the location manager


Autodetect graphics

This game demo has an autodetect graphics feature. Essentially it checks the framerate and based on that it sets a graphics quality setting. Pretty straightforward stuff.

There's another script to simulate specific hardware tiers.

Save/Load System

Flowchart
Flowchart

Instead of building this from ground up I used the SaveGameFree package as the base for the system. It supports all the basic datatypes as well as custom data models which is what I intended to use. This is the free version of the package; you can check out the full paid one which has a whole lot of features.

It's a simple system. There is a base model class which defines what kind of data can be saved. In runtime there is always one instance of this model that is constantly updated and saved to disk at specific intervals or manually.

The saving and loading scripts implement the ISaving and ILoading interfaces. The reason for this was that if at some point I wanted a different way of storing the data it would be easy to plug it in and wouldn't need more code to be written in the main save load system scripts.

The system allows for auto saving at intervals, manual saves, checkpoints and autoloads newest save on start.

Interaction System

There were several iterations of this. This implementation was written from scratch for the underground level that I talked about in my other blog post ( read here : https://www.3dbynoobs.com/post/how-to-design-a-game-level ).

The design is fairly straightforward for a puzzle level, there are 2 types of scripts; one is the trigger itself, and the other is the triggerable. Each trigger can have multiple triggerables.

Essentially, when a trigger is executed each triggerable linked to that trigger is triggered.

For example, if there is a trigger like a switch, if the player hits it, it could open a door, turn on a light and start the ceiling fan. A simple event and consequence model.


This is the base trigger script which other kinds of triggers inherit from.


This is a simple toggle trigger, like a switch. There is a simple cooldown as well to act as a debounce mechanism which can sometimes occur.


This is a simple triggerable. It activates a simple bridge for the player to cross over.

Cutscenes

This project involved a bit of cinematics as well using timelines and cinemachine for camera work. Unity's Live capture app was used for facial expressions and head movement.

I designed the neighbourhood to resemble an Indian suburban location since that is where the story begins.

You can watch a snippet of it here:



Consolation prizes

Although there are a few more things worth mentioning. (There's not enough documentation for these and I don't remember much of it)

  1. Custom grass solution using RenderMeshIndirect API (Unity - Scripting API: Graphics.RenderMeshIndirect )

    1. The reason this was abandoned was because there was no LODs and culling was really broken (binning issue).

    2. This method is obsolete now because GPU Resident Drawer does it with less work. BatchRendererGroup API is pretty amazing stuff.

  2. Day night system

    1. Custom lightweight skybox solution which used vertex lighting and had a simple 3 colour sky model ( ground, horizon and zenith ).

    2. Custom editor tool to record colours of a surrounding into vertex colours of a sphere.

  3. Custom Analytics and Statistics for testing

    1. Custom Firestore REST API

    2. Records essential performance metrics

    3. Records position data

      1. Created a custom position data visualiser in editor

  4. Simple portal implementation where momentum is carried through the portal.

  5. Custom Superbase REST Authentication with automatic token refresh

    1. Android Keystore wrapper

  6. Stats buff system



Project Gallery

Subscribe for Updates

© 2020–2025 3DbyNoobs by Abhishek Jathan.

All rights reserved.

bottom of page