Sketch
http://165.232.166.95:5500
Concept
I decided to implement a clicker/incremental game with a unique twist, combining elements from popular titles like To The Core, Cookie Clicker, and Adventure Capitalist. The game revolves around hunting flying shapes using a cursor with an attached box (scope/aim). Players damage enemy shapes when they’re inside this box, earning resources to upgrade skills in a talent tree. The game also features levels for long-term progression and bonuses.
Game Mechanics and Achievements
The core gameplay involves killing enemies that appear on the screen using an aiming device attached to the cursor. Each enemy defeated rewards the player with experience and money. Leveling up releases resources, while money allows for upgrades in the talent tree. One of the most challenging and rewarding aspects of development was balancing the game’s economy. After extensive experimentation and research, I developed formulas that strike a balance between challenge and progression, ensuring the game is neither too easy nor too difficult. Here is the mathematical framework for the economics of the “Cubix” game.
Core Mechanics
Player Progression
The player’s power increases through two main avenues:
1. Killing mobs to gain experience and resources
2. Upgrading skills to become more effective at killing
Experience and Leveling
XP_{gained} = Base_{XP} * (1 + Level_{mob} * 0.1)
Where Base_{XP} is a constant value for each mob type, and Level_{mob} is the level of the mob killed.
The experience required to level up follows an exponential curve:
XP_{required} = 100 * 1.1^{Level_{player}}
This ensures that leveling becomes progressively more challenging.
Resource Generation
Resources (e.g., gold) dropped by mobs calculated similarly:
Gold_{dropped} = Base_{gold} * (1 + Level_{mob} * 0.15)
Skill Upgrades
Each skill has multiple levels, with increasing costs and effects. The cost to upgrade a skill follows this formula:
Cost_{upgrade} = Base_{cost} * 1.5^{Level_{skill}}
The effect of the skill (e.g., damage increase) is:
Effect_{skill} = Base_{effect} * (1 + Level_{skill} * 0.2)
Mob Scaling
To keep the game challenging, mob health and damage can scale with the player’s level:
Health_{mob} = Base_{health} * 1.2^{Level_{player}}
Damage_{mob} = Base_{damage} * 1.15^{Level_{player}}
A significant technical achievement is the implementation of local progress saving using localStorage. This feature required considerable effort but greatly enhances the player experience by allowing seamless continuation of gameplay across sessions.
class Storage {
constructor() {
this.spawnRate = [1000, 2000];
this.spawnChances = [0.5, 0.3, 0.1];
this.maxEnemies = 100;
this.balance = 0;
this.level = 0;
this.xp = 0;
this.damage = 20;
this.hp = 20;
this.regen = 1;
this.interval = 1000;
this.crit = 10;
this.critChance = 0.12;
this.armor = 0;
this.skills = defaultSkills;
this.scopeSize = 100;
}
getSkillEffect(id) {
let skill = this.skills.find(skill => skill.id === id);
if (skill.level === 0) {
return 0;
}
return int(skill.baseEffect * (1 + skill.level * 0.2))
}
reset() {
this.spawnRate = [1000, 2000];
this.spawnChances = [0.5, 0.3, 0.1];
this.maxEnemies = 100;
this.balance = 0;
this.level = 0;
this.xp = 0;
this.damage = 20;
this.hp = 20;
this.regen = 1;
this.interval = 1000;
this.crit = 10;
this.critChance = 0.12;
this.armor = 0;
this.skills = defaultSkills;
this.scopeSize = 100;
this.save();
}
load() {
let save = localStorage.getItem("save");
if (!save) {
this.save();
} else {
let data = JSON.parse(save);
this.spawnRate = data.spawnRate;
this.spawnChances = data.spawnChances;
this.maxEnemies = data.maxEnemies;
this.balance = data.balance;
this.damage = data.damage;
this.hp = data.hp;
this.level = data.level;
this.xp = data.xp;
this.regen = data.regen;
this.interval = data.interval;
this.crit = data.crit;
this.critChance = data.critChance;
this.armor = data.armor;
this.skills = data.skills;
this.scopeSize = data.scopeSize
}
}
save() {
localStorage.setItem("save", JSON.stringify(this));
}
}
Additionally, the game’s performance has been optimized to handle multiple moving elements without significant FPS drops, with only minor issues arising when enemy rotation was introduced (disabled for the FPS sake).
Design
Areas for Improvement and Challenges
While the project has made significant progress, there are several areas for future improvement. The settings button on the home screen is currently non-functional and needs to be implemented. Expanding the variety of enemies and introducing the ability to prestige levels are also planned enhancements that will add depth to the gameplay.
Also I encountered a significant scaling challenge when testing the game on devices with different screen sizes and resolutions. The game elements, including flying shapes, cursor box, and UI components, were not displaying consistently across various machines. To resolve this, I implemented a scaling solution using scale factor based on canvas size and baseWidth with baseHeight, that ensures optimal display across different screen sizes.
Any way one of the main challenges encountered was optimizing performance, particularly when adding rotation to the enemies. This issue highlighted the need for careful consideration of graphical elements and their impact on game performance. Moving forward, further optimization and potentially exploring alternative rendering techniques could help address these performance concerns and allow for more complex visual elements in the game.