A fun and engaging platformer where players navigate challenges as a clever frog.
About
Frolic Frog is a thrilling vertical platformer that invites players to leap into a vibrant world filled with challenges and excitement. As you guide our charismatic frog through hazardous waters and perilous obstacles, you'll need sharp reflexes and strategic thinking to reach new heights and set high scores.
Project Details
Game Title: Frolic Frog
Genre: Vertical Platformer
Platform: PC
Development Tools: Unity, C#
Game Features:
In Frolic Frog, platforms, enemies, and other obstacles are dynamically spawned as the player progresses upwards, ensuring a unique playthrough each time. The game strikes a balance between easy and challenging platforms to keep players engaged. The spawning system is based on the player's position, ensuring that they are continually challenged as they ascend.
Implementation
Platforms are spawned at runtime based on the player's current height, with randomisation applied to their X and Y coordinates. Different platform types (e.g. breakable platforms, moving platforms, lily pads) are selected accordingly depending on their probability. To enhance player engagement, I implemented a difficulty curve that gradually increases as the player ascends.
Design Approach
At the start, players encounter a high density of platforms and fewer obstacles, making it easier to learn the mechanics. As players progress higher, the number of platforms decreases while the frequency and variety of obstacles increase, creating a more challenging experience.
Click for details
×
Dynamic Platform Spawning This video demonstrates the procedural spawning of platforms in Frolic Frog, showcasing how lily pads are more common in the starting areas, while crocodiles and rocks become more frequent obstacles as the player ascends. Watch as the game adapts to the player's height, creating a unique gameplay experience every time
Abundant Starting Platforms In this image, players are greeted with numerous platforms and zero obstacles, providing a safe environment to learn game mechanics. This ensures a smooth introduction to the gameplay experience.
Challenging Pathways Begin As players progress, the number of available platforms decreases, leading to a more focused pathway. Here, players encounter their first challenge with fewer platforms and the need to navigate carefully.
Introduction of Obstacles This image illustrates a single path with a limited number of platforms and the introduction of obstacles. Players must now navigate around rocks, adding an extra layer of challenge to their ascent.
Increased Difficulty Ahead The final image presents a formidable challenge with a narrow pathway blocked by three crocodiles and three rocks. This setup tests players' skills, requiring precise jumps and careful timing to overcome the obstacles.
Platform Spawning
This snippet focuses on the primary platform spawning logic, its the foundation for the procedural generation and shows how the game ensures platforms are consistently generated as the player progresses.
Special Platform & Obstacles
This snippet shows how special platforms such as breakable platforms or enemies are added dynamically with a random chance.
Difficulty Curve
The code snippet shows the platforms are generated depending on the player's current score. Lower scores increase the likelihood of spawning drop platforms, making it easier for players to learn the mechanics of the game. As players progress and their scores rise, the spawning logic adjusts, providing a gradual increase in difficulty and challenge.
Challenges
Randomised Spawn Locations
Challange:
Ensuring all the platforms spawn in varied but accessible locations to prevent players from becoming stuck or overwhelmed.
Solution:
I implemented constraints to the x coordinates for platform spawning based on player position and predefined limits to maintain consistent accessibility.
Dynamic Difficulty Adjustment
Challange:
Designing the spawning logic to increase difficulty without creating frustration, particularly for new players.
Solution:
Gradually reducing the number of platforms and increasing the variety and frequency of obstacles as players ascend, ensuring they have enough safe areas to practice their skills.
Description
Object pooling is used to optimize the performance of effects in the game, such as particles and special visuals. Instead of repeatedly creating and destroying these objects, a pool of pre-initialized objects is recycled, reducing memory usage and ensuring smoother gameplay.
Implementation
The game uses object pooling for visual effects such as particle bursts when the player jumps. This ensures that the game runs smoothly, especially during intense moments with multiple effects on-screen.
Design Approach
I decided to implement object pooling for the jump effect as a way to practice and enhance my understanding of pooling techniques in game development. While I only needed a single instance for the jump effect, utilizing pooling allowed me to experiment with the concept and prepare for potential future scenarios where multiple instances might be required. This practice also contributes to better performance management in cases where instantiating and destroying objects could lead to overhead.
Click for details
×
Object Pooling The effect prefab is set active / deactive during the players jumps rather than spawning new instances in each time
Object Pooling
This code snippet demonstrates the implementation of an Object Pooling system for managing visual effects, specifically designed for enhancing performance and optimizing resource usage in the game.
Object Pooling
In the game, the PoolManager is utilized to efficiently manage visual effects triggered by various actions, such as when a player jumps or interacts with an object. Instead of creating new effect instances on the fly, which can be taxing on performance, the game activates pre-initialized objects from the pool. This results in faster response times and smoother graphics, allowing for a more engaging player experience.
Challenges
Limited Activation of Objects
Challange:
In some cases, the object pool may have more objects than necessary, leading to scenarios where only one object is activated at a time. This limits the effectiveness of the pooling system.
Solution:
Adjust the pool size based on gameplay requirements.
Object Reset Timing
Challange:
If objects reset (deactivate) too quickly, players may not see the effects when needed, causing confusion or dissatisfaction with the gameplay.
Solution:
I addressed this by implementing a delay in the reset of the pool until I was confident that there would be no further need for the effect. This allowed for the perfect timing to reset the effect back into the pool, ensuring that players experience the intended visuals without interruption.
Description
In Frolic Frog, obstacles such as rocks, crocodiles, and breakable platforms challenge players as they ascend. Rocks serve as barriers, crocodiles add dynamic threats, and breakable platforms require strategic timing. This variety keeps gameplay engaging and encourages players to adapt their strategies.
Implementation
Obstacles are spawned based on the player's height and progress using conditional statements that check the player’s score. For instance, as players progress, the frequency and variety of obstacles increase to match their skill level.
Design Approach
The design of obstacles ensures a balanced challenge that evolves with the player. Initially, simple obstacles allow for skill familiarization. As players ascend, obstacle density and complexity increase, promoting advanced strategies. Careful placement encourages exploration, with rocks leading to alternative routes and crocodiles creating intense moments. Playtesting informed adjustments to maintain gameplay flow and player engagement.
Obstacle Spawning
This snippet shows how obstacles like rocks and crocodiles are spawned dynamically as the player ascends.
Adjusting Difficulty with Height
This snippet shows how the chances of spawning certain obstacles increase as the player reaches higher points in the game, adding difficulty.
Obstacle Collision Logic
This snippet shows how the player interacts with obstacles, like taking damage after hitting a rock or crocodile.
Challenges
Obstacle Spawning Logic
Challange:
Ensuring obstacles are spaced in such a way that the player has a fair chance of navigating between them, without feeling overwhelmed or getting stuck in unwinnable situations.
Solution:
I implemented random spawn positioning with predefined limits for obstacle placement. Additionally, I ensured that paths around obstacles are always possible by adjusting spawn locations if needed. Playtesting was key to fine-tuning these values to maintain game balance.
Dynamic Difficulty Adjustment
Challange:
Ensuring that obstacles like crocodiles, rocks, and bounce pads don't make the game overly difficult too early, while still maintaining a sense of progression and challenge as the player advances.
Solution:
I adjusted the obstacle spawn rates based on the player's score and height in the game. By using conditional statements, I ensured obstacles like rocks and crocodiles only spawn in higher areas, while easier obstacles appear in the early game. This creates a natural difficulty curve, allowing players to practice early and face tougher challenges later.
Description
The player progression system in the game ensures that players feel a sense of advancement and reward as they continue to play. It tracks the player's score, money, and unlocks skins through a shop system. Players can earn currency by progressing through the game, which they can then use to unlock new skins, adding an extra layer of personalization and long-term engagement. Scores and currency are saved across sessions, ensuring that player progress is never lost.
Implementation
The player’s highest score, current score, and in-game currency are stored persistently using a saving system. When the player earns enough in-game currency, they can access the shop to unlock new skins or items. The shop system checks for available funds and displays available skins for purchase. After unlocking, the selected skin is saved and applied to the player character on the next session or immediately after purchase.
Design Approach
The design focuses on long-term engagement. By offering a shop where players can unlock new skins, the game incentivizes replay ability and introduces goals beyond just achieving a high score. The skin system is designed to appeal to player personalization, giving them a sense of ownership over their character.
The saving system ensures continuity, allowing players to feel that their achievements and progression are meaningful and persist across sessions. This reduces frustration and increases motivation to continue playing and unlocking rewards.
Click for details
×
Character Unlock This video demonstrates the Frolic Frog shop system, where players can purchase different frog skins. As the player selects a skin to unlock, you’ll see how the frog's status is updated in the inspector, indicating whether a specific skin is locked or unlocked. When a frog is successfully purchased, the shop system updates the selection, deducts the currency, and sets the frog's status to unlocked, allowing players to use their newly acquired skin in future sessions.
End Screen In this video, you’ll see how the game menu dynamically updates the player's current score and currency (flies) after each run. When the player dies, the final score and earned flies are displayed on the menu. The system checks if the current score exceeds the highest score from previous sessions. If the new score is higher, it overrides the previous high score and displays a "New High Score!" message on the screen, informing the player of their achievement and updating the high score for future sessions.
Save Manager Script
Manages saving and loading player data, including the current selected frog skin.
Purchasing Skins in the Shop
This allows players to purchase skins using in-game currency (flies). It checks if the player has enough flies, unlocks the skin upon purchase, and deducts the cost from their currency. Unlocked skins and current selections are saved to ensure persistence across sessions.
Obstacle Spawning
The CollectableManager script manages the player's collection of in-game items (flies), keeping track of both the current game session's count and the total collected across all playthroughs. It uses PlayerPrefs to save and retrieve the player's total collection progress, ensuring persistent data between sessions.
Challenges
Managing Character Unlocks and Currency Balance
Challange:
Tracking which characters are unlocked and ensuring the player has enough in-game currency (flies) to make purchases without errors or inconsistencies.
Solution:
I used PlayerPrefs to store the unlock status of characters and the player's current currency. Each character's unlock status is checked when the game loads, and the player’s available flies are retrieved to ensure they can afford a purchase. To avoid bugs, the UpdateUi() function is called every time the player makes a transaction to dynamically adjust button states.
What I Learnt
Dynamic Player Progression Loop:
One of the key challenges in Frog Doodle Jump was designing a dynamic and engaging gameplay loop that scales with player progression. I learned how to adjust the difficulty by increasing the challenge as the player progresses through the game. This included creating a difficulty curve where platforms become faster and obstacles increase in number, making the game more challenging and fun as the player advances. This progression system kept the gameplay fresh and ensured players stayed engaged.
Saving Player Data and High Scores:
For the first time, I implemented a save system to track the player's progress, including their current score, high score, and selected characters. I learned how to serialize data and create a system that would save this information even after the game is closed and reopened. I also worked on displaying this data on the game over screen, ensuring players could see their achievements. This was essential for providing feedback to players about their performance and encouraging replayability.
Shop System and Unlocking Mechanisms:
I developed a shop system where players could unlock new characters using in-game currency. This was my first time building a system that handled unlockable content, and I gained experience in managing an in-game economy. I learned how to save player choices (such as selected characters) and persist these selections across sessions. This experience deepened my understanding of how to balance game progression and reward systems to keep players motivated.
Polishing, Debugging, and Packaging:
During the development of this game, I learned the importance of polishing and debugging. I made sure the game was free of bugs and optimized for performance, particularly when packaging the game for online play. I worked on making sure the user interface was intuitive, the controls were smooth, and the overall experience was free of interruptions. This was my first time preparing a game for public release and I learned how to debug efficiently and polish the final product for a professional standard.
Retrospective
Object Pooling:
I implemented object pooling for the jump effect, as it allowed me to avoid constantly instantiating and destroying objects. However, I only applied it to a single type of object. In retrospect, I realized that platforms could benefit greatly from object pooling as well. Rather than destroying and spawning new platform objects as they leave the screen, I could have instead deactivated them, moved them to a new position, and then reactivated them. This would have reduced unnecessary object creation, thus improving performance, especially if the game expanded in scope. While it didn't significantly impact gameplay performance due to the small scale of the project, applying object pooling more broadly would have followed best practices and helped the game run more efficiently. Moving forward, I plan to implement object pooling more comprehensively in future projects, particularly for dynamic objects like platforms, obstacles, and enemies.
Unplanned Features:
The addition of new characters and a shop system, which wasn't initially planned, significantly extended the project’s timeline. While it enhanced the game’s depth and replayability, it also created unforeseen delays. In hindsight, incorporating the shop system added complexity that could have been avoided or planned better in the early stages. Moving forward, I plan to be more mindful of scope creep and ensure that features are fully scoped out before implementation. This will help avoid delays and improve the overall development process.