A turn-based tactical card battle game on a 5×7 grid. Deploy units, cast spells, and destroy the enemy base — with rule-based opponents, boss challenges, story progression, and WebSocket multiplayer.
Overview
Age of War is a turn-based tactical card battle game built entirely with HTML5, CSS3, and
vanilla JavaScript. Players command units from three factions across a 5×7 battlefield,
deploying cards, moving units, and using skills to destroy the enemy base. The game
features a full rule-based scoring opponent with configurable strategy weights, three
unique boss
encounters, a story-driven adventure mode with progression, and real-time WebSocket
multiplayer.
The project was born from a desire to build a complete card battle experience — not just
the rules engine, but the full presentation: character selection screens, event-driven
story maps, detailed unit cards with tooltips, battle HUD with action points and health
tracking, and a polished dark-fantasy visual theme.
Gameplay & Battle System
Each battle unfolds on a 5×7 grid with both bases on opposite sides. The
turn structure is split into two phases:
Deployment Phase. Spend Action Points (AP) to play units from your
hand or cast spells. First two draws cost 1 AP each; subsequent draws cost 2 AP.
Maximum hand size is 7 cards.
Battle Phase. Select friendly units to move, attack, or use their
unique faction skills. Normal units must choose between moving or attacking each
turn; the Shadow Assassin can do both.
Three factions bring distinct tactical identities:
Human. Shield Bearers defend with damage reduction; Archers have a
1/6
chance of double damage; Swordsmen deal splash damage to adjacent enemies.
Shadow. Shadow Assassins move and attack in one turn; Shadow Mages
swap positions with allies; Shadow Lords corrupt defeated enemies into allied units.
Beast. Raging Wolves charge and knock back; Minotaur Warriors
buff nearby allies; Frost Dragons freeze targets for one turn.
Spell cards add another layer: Healing Kit, Shield Card, Draw Card, Reset Card, and the
rare Ice Nova that freezes all enemies for three turns.
Opponent System
The opponent uses a rule-based scoring system with configurable
strategy weights. Each decision is evaluated across ten dimensions:
Attack Priority · Move Towards Enemy · Protect Low Health
All weights start at 1.0 (attack priority at 2.0) and can be adjusted through the
developer panel. The opponent tracks match statistics across the last 50 games, supports
data
export/import for strategy sharing, and can run fully autonomous matches for up to 100
rounds — useful for balance testing and observing emergent behavior.
A separate simplified battle simulation runs in isolated instances
without
affecting the main game state, allowing rapid prototyping of new unit ideas.
Boss Challenges
Three boss encounters each break normal rules in their own way:
Shadow Council. An assassin-type boss that summons a low-level
shadow
every turn for free, uses only shadow faction units, and recovers only 1 AP per
turn with a fragile 5-HP base.
Frost Queen. A control boss with a 30% freeze chance after any
enemy
movement and exclusive access to the Ice Nova spell. Recovers 3 AP per turn.
Iron Patriarch. A buff boss recruiting only humans; each adjacent
human adds +1 attack every turn. When the base is destroyed, a devastating
Counterattack Colossus spawns and marches toward the player.
Story Mode & Progression
The adventure mode follows a chosen hero through an event-driven map with branching
paths.
Events include battles, taverns, shops, crossroads, springs, awakening altars, and
supply depots. Each hero starts with a predefined deck:
Iron Wall Guardian. Defensive human deck focused on shields and
sustain.
Shadow Hunter. Aggressive shadow deck with assassination and
corruption.
Beastmaster. Beast deck built around the Raging Wolf, Minotaur, and
Frost Dragon — each with unique synergy and play patterns.
Progress is saved after every completed event. Characters level up (max Lv.6), gaining
max HP and unlocking new strategic options. Gold earned from victories is spent in
shops and taverns to refine decks. The system is designed so that an interrupted
session can be resumed exactly where it left off.
Multiplayer & Architecture
WebSocket multiplayer runs on a Node.js server using the ws library. Room
IDs
sync game state between two clients; the server forwards messages without authoritative
rule validation, keeping the architecture lightweight for prototyping. URL parameters
(?player=1&room=testroom) set up matches instantly.
The frontend is built with vanilla ES6+ modules: units.js defines all
cards and abilities; ui-manager.js renders the board, hand, and tooltips;
player-experience.js handles perspective, input states, and onboarding
guidance. All game logic is currently inline in game.html, with a clear
path
to modular separation.
Reflection
Age of War was built to test a card game I had designed on paper. Before printing
anything, I needed to know whether the rules actually worked: whether every unit, spell,
and boss mechanic interacted cleanly with movement, the AP economy, hand limits, and
rule scoring. On paper I could only imagine those interactions. In a running system I
could watch them happen.
That changed what the hard part was. It was not adding features — it was checking whether
the opponent could use the features in ways that felt intentional rather than random. A
card game only works if the other side plays it properly, so the digital version needed
an opponent before it could test anything at all.
The weight-based scoring system was a deliberate choice: instead of building a black-box
neural net, I wanted a transparent scoring model where I could see why the opponent made
each decision. That transparency was the point — if I could not explain a move, I could
not tell whether a rule was broken or the opponent was. Tuning those ten weights taught
me more about game balance than any spreadsheet could, because every adjustment showed
up immediately in how the opponent played.
When the opponent suddenly started protecting wounded units instead of rushing the base,
I knew two things at once: the system was starting to think like a player, and the card
game underneath it was holding up under real play. That was the moment the digital
version stopped being a test and started being evidence.