Overview
The essence system in Elemental Battlecards tracks which elemental types have been activated through direct attacks. Each player has an essence Set that stores activated essence types. Filling all 6 essences is one of the victory conditions.
Implementation Note: While the codebase includes an EssenceManager class in /game_objects/essences.js, the actual game implementation uses a native JavaScript Set for essence tracking, as seen in GameScene.js.
Actual Implementation (GameScene)
Essences are implemented as a JavaScript Set in the game:
// From Frontend/src/scenes/GameScene.js:199-200
this.player.essences = new Set();
this.opponent.essences = new Set();
Initial State: The Set starts empty. Essence types are added via the add() method when direct attacks are performed.
The six essence types:
- Fire (fuego)
- Water (agua)
- Plant (planta)
- Light (luz)
- Shadow (sombra)
- Spirit (espiritu)
Properties
A JavaScript Set containing activated essence types. Empty at game start, populated through direct attacks.Type: Set<string>Possible values:
'fuego' (Fire)
'agua' (Water)
'planta' (Plant)
'luz' (Light)
'sombra' (Shadow)
'espiritu' (Spirit)
Key Operations
fillEssence(essenceType)
Adds an essence type to the player’s Set. This method is dynamically added to Player instances in GameScene.
The type of essence to activate (using CARD_TYPES values)
// From Frontend/src/scenes/GameScene.js:203-214
playerInstance.fillEssence = function(essenceType) {
// Only add if not already present
if (!this.essences.has(essenceType)) {
this.essences.add(essenceType);
console.log('[GameScene] Essence activated', {
playerId: this.id,
essenceType,
total: this.essences.size
});
// Emit event for UI update
this.scene.events.emit('essence-activated', this.id, essenceType);
} else {
console.log('[GameScene] Essence already activated', {
playerId: this.id,
essenceType
});
}
};
Usage:
// Perform direct attack and fill essence
this.player.fillEssence('fuego'); // Adds fire essence
this.player.fillEssence('agua'); // Adds water essence
this.player.fillEssence('fuego'); // No effect - already added
has(essenceType)
Checks if a specific essence type is in the Set.
The essence type to check
Returns true if the essence is active, false otherwise
// Check if player has fire essence
if (player.essences.has('fuego')) {
console.log('Fire essence is active!');
}
// Check before adding
if (!player.essences.has('agua')) {
player.essences.add('agua');
}
size
Returns the number of activated essences.
The count of unique essence types in the Set (0-6)
// From Frontend/src/scenes/GameScene.js:1336-1343
// Check for victory condition
if (this.player.essences.size === 6) {
console.log('[GameScene] VICTORY: PLAYER (filled all 6 essences)');
return 'player';
}
// Display count
console.log(`Player has ${this.player.essences.size} essences`);
Complete Example
// From Frontend/src/scenes/GameScene.js
class GameScene extends Phaser.Scene {
create() {
// Initialize essence Sets for both players
this.player.essences = new Set();
this.opponent.essences = new Set();
// Add fillEssence method to players
const addFillEssence = (playerInstance) => {
playerInstance.fillEssence = function(essenceType) {
if (!this.essences.has(essenceType)) {
this.essences.add(essenceType);
console.log('[GameScene] Essence activated', {
playerId: this.id,
essenceType,
total: this.essences.size
});
this.scene.events.emit('essence-activated', this.id, essenceType);
}
};
};
addFillEssence(this.player);
addFillEssence(this.opponent);
}
handleDirectAttack(attackingCard) {
// Get card type
const attackerData = attackingCard.getData('cardData');
// Fill essence matching the attacking card's type
this.player.fillEssence(attackerData.type);
// Check for victory
if (this.player.essences.size === 6) {
this.endGame('player');
}
}
checkVictoryConditions() {
// Check essence victory condition
if (this.player.essences.size === 6) {
console.log('[GameScene] VICTORY: PLAYER (filled all 6 essences)');
return 'player';
}
if (this.opponent.essences.size === 6) {
console.log('[GameScene] VICTORY: OPPONENT (filled all 6 essences)');
return 'opponent';
}
return null;
}
}
How Essences Are Earned
Essences are filled through direct attacks only - when a player attacks while the opponent has no cards on the field:
// From Frontend/src/scenes/GameScene.js:1237-1241
// Direct attack handling
console.log('[GameScene] Player performs direct attack', {
attackerType: attackerData.type,
attackerIndex: attackingCardObject.getData('fieldIndex')
});
this.player.fillEssence(attackerData.type);
Key points:
- Direct attacks only occur when opponent’s field is empty
- Each direct attack fills the essence matching the attacking card’s type
- Each essence can only be filled once (Set prevents duplicates)
- Need to perform direct attacks with all 6 different card types to win
UI Integration
Essences are visually displayed in the UIScene:
// From Frontend/src/scenes/uiScene.js
// Listen for essence activation events
this.gameScene.events.on('essence-activated', (playerId, essenceType) => {
// Update orb visual for the essence type
this.updateEssenceOrb(playerId, essenceType, true);
});
function updateEssenceOrb(playerId, essenceType, isActive) {
const orb = this.essenceOrbs[playerId][essenceType];
// Light up the orb or dim it
orb.setAlpha(isActive ? 1.0 : 0.3);
}
Visual Layout:
- 12 total orbs (6 per player)
- Arranged in two triangular patterns per player
- Gray when inactive, lit when active
- Arrows show type advantage relationships
Card Types Reference
Use the CARD_TYPES constant for type-safe essence operations:
import { CARD_TYPES as CardTypes } from '../helpers/constants.js';
// Available card types:
CardTypes.FUEGO // 'fuego' - Fire
CardTypes.AGUA // 'agua' - Water
CardTypes.PLANTA // 'planta' - Plant
CardTypes.LUZ // 'luz' - Light
CardTypes.SOMBRA // 'sombra' - Shadow
CardTypes.ESPIRITU // 'espiritu' - Spirit
The EssenceManager Class (Unused)
While the codebase includes an EssenceManager class in /Frontend/src/game_objects/essences.js, it is not used in the actual game. The class provides an object-based approach to essence tracking with methods like activate(), has(), and getAll(), but GameScene implements essence tracking using native JavaScript Sets instead.
If you’re extending the game, you can choose to:
- Use the current implementation: Continue with
Set<string> (simpler, native)
- Migrate to EssenceManager: Refactor to use the class (more structured, extensible)
The EssenceManager class source can be found in /Frontend/src/game_objects/essences.js if needed for future development.