Skip to content

Add ship experience#192

Merged
dominik-zeglen merged 4 commits into
mainfrom
add-ship-experience
Jul 20, 2025
Merged

Add ship experience#192
dominik-zeglen merged 4 commits into
mainfrom
add-ship-experience

Conversation

@dominik-zeglen
Copy link
Copy Markdown
Collaborator

This PR adds experience mechanics to the game ✨
From this moment, a ship can level up by gaining experience in combat. Each rank grants +10% stacking bonus to max hp and damage output.

This PR also enables further development of ship modifiers, such as support ship auras, environmental debuffs, research effects, etc.

@dominik-zeglen dominik-zeglen requested a review from Copilot July 20, 2025 10:33
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements ship experience mechanics that allow ships to gain experience in combat and level up for stat bonuses. Ships now earn experience when destroying enemies, with each rank providing a +10% stacking bonus to max HP and damage output.

  • Adds experience tracking component with rank progression system
  • Implements experience gain from combat kills with distribution among attackers
  • Introduces modifier system for recalculating stats when ships level up

Reviewed Changes

Copilot reviewed 20 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ui/components/ExperienceBar/ExperienceBar.tsx New component displaying experience progress and rank
ui/components/Panel/Panel.tsx Integrates experience bar into ship UI panel
core/components/experience.ts Core experience component with rank calculation logic
core/components/hitpoints.ts Refactored to support modifiers and damage tracking
core/components/damage.ts Restructured to support modifier-based damage calculation
core/systems/modifierRecalculatingSystem.ts New system for recalculating modified stats
core/systems/deadUnregistering.ts Awards experience to attackers when entities die
core/archetypes/ship.ts Adds experience component to ship creation

return ranks.findIndex((threshold) => exp < threshold);
}

export function addExperience(
Copy link

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function updates modifiers and adds the recalculate tag even when rank doesn't change. This could cause unnecessary recalculations. Move the modifier updates and tag addition inside the if (newRank > entity.cp.experience.rank) block.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +12
const rank = getRank(amount);
const progress = rank === 5 ? 0 : amount / ranks[rank];
const expLabel = rank === 5 ? "Max Rank" : `${amount}/${ranks[rank]}`;
Copy link

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number 5 is used to check for max rank. Consider using ranks.length - 1 or defining a constant like MAX_RANK to make the code more maintainable.

Suggested change
const rank = getRank(amount);
const progress = rank === 5 ? 0 : amount / ranks[rank];
const expLabel = rank === 5 ? "Max Rank" : `${amount}/${ranks[rank]}`;
const MAX_RANK = ranks.length - 1;
const rank = getRank(amount);
const progress = rank === MAX_RANK ? 0 : amount / ranks[rank];
const expLabel = rank === MAX_RANK ? "Max Rank" : `${amount}/${ranks[rank]}`;

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +12
const progress = rank === 5 ? 0 : amount / ranks[rank];
const expLabel = rank === 5 ? "Max Rank" : `${amount}/${ranks[rank]}`;
Copy link

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another instance of magic number 5. This should use the same constant as suggested for line 11 to ensure consistency.

Suggested change
const progress = rank === 5 ? 0 : amount / ranks[rank];
const expLabel = rank === 5 ? "Max Rank" : `${amount}/${ranks[rank]}`;
const progress = rank === MAX_RANK ? 0 : amount / ranks[rank];
const expLabel = rank === MAX_RANK ? "Max Rank" : `${amount}/${ranks[rank]}`;

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +58
const exp =
expValues[entity.cp.dockable?.size || "small"] / attackers.length;
for (const attackerId of attackers) {
const attacker = this.sim.get(attackerId);
if (attacker?.hasComponents(["experience"])) {
addExperience(attacker, exp);
Copy link

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Division by zero will occur if attackers.length is 0. Add a check to ensure attackers array is not empty before calculating experience distribution.

Suggested change
const exp =
expValues[entity.cp.dockable?.size || "small"] / attackers.length;
for (const attackerId of attackers) {
const attacker = this.sim.get(attackerId);
if (attacker?.hasComponents(["experience"])) {
addExperience(attacker, exp);
if (attackers.length > 0) {
const exp =
expValues[entity.cp.dockable?.size || "small"] / attackers.length;
for (const attackerId of attackers) {
const attacker = this.sim.get(attackerId);
if (attacker?.hasComponents(["experience"])) {
addExperience(attacker, exp);
}

Copilot uses AI. Check for mistakes.
entity.cp.hitpoints.shield.value - delta
);
delta -= Math.min(entity.cp.hitpoints.shield.value, value);
delta += Math.min(entity.cp.hitpoints.shield.value, value);
Copy link

Copilot AI Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line uses += but should use -= to correctly calculate remaining damage after shield absorption. The current code would add the absorbed shield damage back to delta instead of subtracting it.

Suggested change
delta += Math.min(entity.cp.hitpoints.shield.value, value);
delta -= Math.min(entity.cp.hitpoints.shield.value, value);

Copilot uses AI. Check for mistakes.
@dominik-zeglen dominik-zeglen merged commit 02aec99 into main Jul 20, 2025
1 check passed
@dominik-zeglen dominik-zeglen deleted the add-ship-experience branch July 20, 2025 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants