Responsive mobile gameplay
A major focus was creating controls that felt immediate and satisfying on a mobile device. Since the game was inspired by fast-paced arcade gameplay, the player's movement needed to feel readable and reactive.
University project
A 2D mobile endless runner made in Unity by a team of six over 10 weeks.

In motion
Selected moments from the team's gameplay recording, showing the systems and player-facing features in context.




Overview
RBRC is a 2D mobile game developed in Unity by a team of six over 10 weeks. The player controls a bird escaping from the police while avoiding obstacles, surviving hazards, and moving through a fast-paced side-scrolling environment.
The project focused on creating a fun and accessible mobile gameplay experience with responsive controls, readable action, and a simple loop that players could understand quickly.
Role
In this project, I was responsible for programming and worked on several of the game's core systems in Unity. Since this was one of my first group projects, it gave me experience both in implementing gameplay features and in developing systems that had to work together as part of a larger team production.
My work included implementing and refining parts of the game flow, such as menu navigation, UI-related systems, gameplay behaviour, and player-facing features. I also worked with testing, debugging, and iteration to improve stability and make the game feel more coherent and functional as a complete mobile experience.
In addition to gameplay programming, I was involved in integrating and working with assets, interface elements, and other technical parts of the project inside Unity. This project became an important step in developing my understanding of team-based game development, especially how programming supports both the player experience and the overall structure of the game.
Design focus
A major focus was creating controls that felt immediate and satisfying on a mobile device. Since the game was inspired by fast-paced arcade gameplay, the player's movement needed to feel readable and reactive.
My programming work aimed to support simple but reliable systems that could be expanded during development. This helped the team test ideas quickly and build the overall experience more efficiently.
The game was designed around a fast and accessible loop. The player should quickly understand the objective, stay engaged through movement and obstacles, and feel encouraged to try again for a better result.
Implementation
Implemented and refined gameplay behaviour so the player experience felt responsive, readable, and suitable for short mobile play sessions.
Worked on menu navigation and interface-related systems that supported the game's start, options, statistics, and moment-to-moment flow.
Integrated assets and connected systems inside Unity while making practical decisions around scope, time, and team needs.
Tested features, debugged issues, and adjusted behaviour throughout development to make the final prototype more coherent and stable.
Process
A large part of my contribution involved implementing and refining the game's core gameplay systems. My goal was to make the player experience feel responsive and readable, while keeping the systems flexible enough to be adjusted throughout development.
Because the game was developed in a short time frame, iteration was an important part of the process. I regularly tested features, adjusted gameplay behaviour, and debugged issues to improve both functionality and feel.
Since the project was built in Unity 2D, I worked directly with the engine to integrate mechanics, connect systems, and support the game's moment-to-moment flow. This also meant making practical decisions based on scope, time, and what created the best result for the player.
Code samples
Excerpts from systems I contributed to during the project, lightly trimmed for a focused portfolio presentation.
Keeps the bird within the camera bounds, turns input into immediate vertical motion, and gradually increases the runner speed based on distance travelled.
private void FixedUpdate()
{
UpdateScreenBounds();
if (isFlying && transform.position.y < maxHeight)
{
rigidBody.velocity = new Vector2(
rigidBody.velocity.x,
flapForce
);
}
if (transform.position.y >= maxHeight && rigidBody.velocity.y > 0f)
rigidBody.velocity = new Vector2(rigidBody.velocity.x, 0f);
DataSaver.instance.metersTraveled +=
DataSaver.instance.mps * Time.deltaTime;
DataSaver.instance.mps = startingSpeed
+ accelerationAmplitude
* DataSaver.instance.metersTraveled / 100f;
}Converts a mobile swipe into a projectile direction, applies a cooldown, rejects backwards shots, and prevents the projectile colliding with the player.
private void Shoot(Vector2 start, Vector2 end)
{
if (Time.time - lastShootTime < shootCooldown)
return;
lastShootTime = Time.time;
Vector2 direction = end - start;
direction = direction.magnitude < minSwipeDistance
? Vector2.right
: direction.normalized;
if (direction.x <= 0f)
direction = Vector2.right;
GameObject projectile = Instantiate(
projectilePrefab,
shootPoint.position,
Quaternion.identity
);
projectile.GetComponent<Rigidbody2D>().velocity =
direction * shootForce;
Physics2D.IgnoreCollision(
projectile.GetComponent<Collider2D>(),
GetComponent<Collider2D>()
);
}Loads the selected language from a JSON resource, stores it for later sessions, and gives missing keys a visible fallback for easier debugging.
public void LoadLocalizedText(string languageCode)
{
TextAsset json = Resources.Load<TextAsset>(
$"Localization/{languageCode}"
);
if (json == null)
{
Debug.LogError("Localization file not found");
return;
}
localizedText = JsonUtility
.FromJson<LocalizationData>(json.text)
.ToDictionary();
currentLanguage = languageCode;
DataSaver.instance.selectedLanguage = languageCode;
UpdateAllTexts();
}
public string GetLocalizedValue(string key) =>
localizedText.TryGetValue(key, out string value)
? value
: $"[{key}]";Reflection
Balancing simplicity with game feel was the main challenge. Because the concept is easy to understand, the quality depends heavily on how responsive and polished the mechanics feel in motion.
The short production period also meant that solutions had to be practical, testable, and possible to improve quickly when needed.
Learning
I learned how important it is to make mechanics not only functional, but clear and enjoyable for the player.
I also improved my ability to test and refine systems during development instead of only focusing on the first implementation.
Next steps
If I continued the project, I would spend more time refining the technical structure behind the gameplay systems and improving long-term flexibility.
I would also continue polishing the player experience through iteration, especially in areas where responsiveness, feedback, and balance could be pushed further.
Overall, this project is valuable in my portfolio because it shows my contribution to a complete game project, my role as a programmer in a team, and my focus on building gameplay that supports the player experience.
Explore