Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
386 commits
Select commit Hold shift + click to select a range
e8b0c95
add combat-components dev page: status chips, VFX animations, SFX audio
kkortes May 30, 2026
bd15815
auto-generate counter variants from STATUS_EFFECTS
kkortes May 30, 2026
3f65f6a
key status-chip each-loops by statusKey so chips don't flicker per tick
kkortes May 30, 2026
1481a00
replace per-status icon overlay on ability tiles with a single buff/d…
kkortes May 30, 2026
db7bf88
tune intimidating roar duration from 3 to 2 ticks
kkortes May 30, 2026
3d333ba
add Stoneskin dwarf signature: self-applied 50% damage-taken buff
kkortes May 30, 2026
e9c2af5
shorten level-up Platinum coin label to Coin
kkortes May 31, 2026
b32c7a9
make Stoneskin a WindDown so the buff lands at cast start
kkortes May 31, 2026
eadbaf5
rename ability appliesTo to target with self/enemy values
kkortes May 31, 2026
f7b6579
Merge branch 'dwarf-signature-stoneskin' into feat/intimidating-roar
kkortes May 31, 2026
f8aac5a
add Warcry human signature and split damage multipliers into incoming…
kkortes May 31, 2026
f6987f4
add hit chance lucky stat and miss animation
kkortes May 31, 2026
797de26
add Smokebomb goblin signature and fix boss-fight miss roll
kkortes May 31, 2026
a5aad97
wire dedicated icons for hitChance, stoneSkin, smokeBomb, warCry, int…
kkortes May 31, 2026
4aabd28
wire alorasTouch icon and reorganize _icons holding pen
kkortes May 31, 2026
6c9bfea
add Gore and Pretending to be humble abilities, fight descriptions, i…
kkortes May 31, 2026
c22b4cb
add emil_jonsson_91@hotmail.com to TESTER_EMAILS
kkortes May 31, 2026
b39a8da
gate Heal now button on isTester
kkortes May 31, 2026
2f7c431
rework DevBar reset buttons, gate element badges, add icons page
kkortes May 31, 2026
d7bccad
build Gear Up vendor/blacksmith cards with level tiers
kkortes May 31, 2026
c18b221
revamp armor as flat damage reduction with armor penetration
kkortes Jun 1, 2026
e909ec4
refine equipment & ability tooltips, reuse StatGroup for stats
kkortes Jun 1, 2026
130c071
add provoke stat: weighted aggro, combat chance display, Steel +10
kkortes Jun 1, 2026
3322ae2
add brawler activity state, rework buff/debuff icons, bump vibe 1.9.7
kkortes Jun 1, 2026
cf0f769
add ability combat stats: 50% Block, Heartpiercer + Powershot weapon,…
kkortes Jun 1, 2026
4e0aebd
remove rarity colors, add brawlers character icon
kkortes Jun 1, 2026
e07dfa4
add test mode toggle, gate battle pass behind tester, fix lock-closed…
kkortes Jun 1, 2026
c128a75
render tooltip descriptions as HTML via $.unsafe, relocate status dur…
kkortes Jun 1, 2026
e895f7f
add flat tooltip gallery page, make tooltip cards prop-driven
kkortes Jun 1, 2026
748672a
rename provoke to provocation, polish tooltips and combat shield
kkortes Jun 1, 2026
3f6b308
fix matchmaking xp range off-by-one, remove debug script
kkortes Jun 1, 2026
75c3853
add weapon arsenal, derive item cost from level, rebalance armor
kkortes Jun 1, 2026
e737393
add eraromik@gmail.com to tester whitelist
kkortes Jun 2, 2026
98f3163
fix
kkortes Jun 2, 2026
cb36f9b
expose game version in topbar, add release-push, rename server dir
kkortes Jun 3, 2026
b02a7d9
chore(release): v0.1.1
kkortes Jun 3, 2026
a31453e
chore(release): v0.1.2
kkortes Jun 3, 2026
cc0f4ee
chore(release): v0.1.3
kkortes Jun 3, 2026
6c32371
fix release-push: set upstream on push
kkortes Jun 3, 2026
71174f0
chore(release): v0.1.4
kkortes Jun 3, 2026
58f25f4
add ability designs dev page and bar damage numbers
kkortes Jun 4, 2026
489951a
refactor ability bars onto shared AbilityBar component
kkortes Jun 4, 2026
e001b36
fix brawler ability resolution, overflow hiding, and slot drag-and-drop
kkortes Jun 5, 2026
26e48c9
add brawler-slot flip animation and shared fight-slot dnd
kkortes Jun 5, 2026
a6dda1e
add ability bar healing numbers and debug creature blacklist
kkortes Jun 6, 2026
f52e54a
refine ability cell designs and inventory layout
kkortes Jun 6, 2026
fc981b8
add desktop click-to-add ability selection + touch dnd
kkortes Jun 6, 2026
273627c
refine equipment tooltip and ability cell UI
kkortes Jun 6, 2026
02deda4
fix plain tooltip to fit content, add text showcase + worktree setup
kkortes Jun 7, 2026
616669a
Merge branch 'claude/compassionate-benz-3ef397' into feat/more-ui-ux-…
kkortes Jun 7, 2026
9e512f5
refactor tooltips and move isTester into settings
kkortes Jun 7, 2026
8070737
add basic-ability styling, shared Cross button, ability bar cursor
kkortes Jun 7, 2026
e88489f
add ability elements with tinting, fix available abilities render
kkortes Jun 7, 2026
11ff1b2
improve dodge animation with duplicating ghost effect
kkortes Jun 7, 2026
666ade1
add equipment type/race system, race dots in gear-up listing
kkortes Jun 8, 2026
eb74f37
bump vieb
kkortes Jun 8, 2026
6358fd4
add form-elements page with Stylecheat disabled-state overrides
kkortes Jun 8, 2026
5ddb0e5
fix mis-nested button/crow tags in form-elements page
kkortes Jun 8, 2026
c693f38
add equipment stats, elemental resistances, and signature abilities
kkortes Jun 9, 2026
e632ba7
add combat preview with state toggles to combat-components page
kkortes Jun 9, 2026
126b2b1
redesign combat status effects as elemental pins with announce and ti…
kkortes Jun 9, 2026
ecb08cd
fix ability bar rendering, dnd ghost, self-cast absorb, floater sizing
kkortes Jun 10, 2026
41c46f1
add tester race-lock skip, tooltip status chips, XP level cap, combat…
kkortes Jun 10, 2026
b57b45f
add heal buffer, ghost hp trail, ability anticipation squish, combat …
kkortes Jun 10, 2026
3436abc
make ability buffs cover attacks on start and end ticks
kkortes Jun 10, 2026
78b56d0
add specialization hint, badge variants, up-to fight slots, ui polish
kkortes Jun 10, 2026
35af7e8
add fight button face lift, sounds browser, weapon swing sfx
kkortes Jun 10, 2026
1b690a2
discount all in-combat healing at fight end via healingReceived ledger
kkortes Jun 10, 2026
11030dd
add tester entity admin tool: /_internal character editor with file-w…
kkortes Jun 10, 2026
b7cbea6
add imagegen tool: fullscreen prompt modal, character schema, spider …
kkortes Jun 11, 2026
881296d
fix select-press arming on unbrawlable states, composite ability bars
kkortes Jun 12, 2026
eb762ed
add weave/skewer/recharge icons, fix spider-web holes, stagger brawl …
kkortes Jun 12, 2026
5398292
add immobilized banner, pve sizing, weave stagger, fight page facelift
kkortes Jun 12, 2026
0667263
add debug playground, balance graphs, stat tooltips, vendor portraits
kkortes Jun 12, 2026
fd742d0
add Skjaldborg shield, Shield Wall ability, element tooltip borders
kkortes Jun 13, 2026
7e0a415
add stomp ability sfx, faster release, tooltip alt-detail reveals
kkortes Jun 14, 2026
b4bd126
fix inventory keybind seeding, debug item levels, combat tweaks
kkortes Jun 14, 2026
5ad8b1d
add ability icons, riposte counter, combat buff fix, tooltip cleanup
kkortes Jun 15, 2026
e70bf43
add character-art page, elemental capstone foes, 25+ level cap, doubl…
kkortes Jun 15, 2026
520eb8d
add poison, execute & boom abilities, new arena foes + portraits
kkortes Jun 15, 2026
2449899
fix: persist bossHighscore so boss-unlock survives MPA reloads
kkortes Jun 15, 2026
8680ffa
fill all combatant kits (12-15, unique), elemental abilities, cleanups
kkortes Jun 15, 2026
3f27b62
fix double victory stinger, add abilities/foes, css cleanups
kkortes Jun 15, 2026
ed4aaa8
add $param filesystem routing + shared page-not-found, gate fights, u…
kkortes Jun 16, 2026
c3edb9e
fix routing dev-server writes; inject route via transformIndexHtml
kkortes Jun 16, 2026
b8aa548
fix boss-unlock gating + defer eager url @[] bindings to data-src
kkortes Jun 16, 2026
6da1ed5
devbar bg fade, shrug 404 icon, potion icon, internal-page tweaks
kkortes Jun 16, 2026
d6c42bf
potion heal button: gradient icon, full-health disable, split drink sfx
kkortes Jun 17, 2026
b4724db
healing system; sticky/position stylecheat migration; ordered boss ga…
kkortes Jun 17, 2026
fe7c629
re-enable medical area bar
kkortes Jun 17, 2026
e58be77
premium badge + account-progression unlock, inventory equip/sell butt…
kkortes Jun 17, 2026
bb66875
circular mugshot brawler hand; coins/premium hidden when logged out
kkortes Jun 18, 2026
097ce48
bump vibe to 2.1.1; enable boot debug logging
kkortes Jun 18, 2026
904a4d2
add equipment-link hexagon design gallery + devbar link
kkortes Jun 18, 2026
7e07658
rename Battle Brawlers to Battleborn Brawlers
kkortes Jun 18, 2026
4be2607
fix
kkortes Jun 18, 2026
74faf2f
Add compiled-build tooling; rename home page to index
kkortes Jun 18, 2026
525f55f
Merge pull request #40 from kkortes/compiled/battleborn-brawlers
kkortes Jun 18, 2026
5fea615
Point Vercel at the compiled build (build:compiled → compiled/)
kkortes Jun 18, 2026
f5ed7cd
Move compiled-build prune to vibe-compiler skipFiles config
kkortes Jun 18, 2026
65ff5db
chore(release): v0.1.5
kkortes Jun 18, 2026
f90bcfc
Merge branch 'game/battleborn-brawlers' into compiled/battleborn-braw…
kkortes Jun 18, 2026
534a111
Fix compiled-build 404s: vendor vibe.css, data-src combatant img
kkortes Jun 18, 2026
1a1925f
Merge branch 'fix/upstream-fixes-to-vibe-compiler' into compiled/batt…
kkortes Jun 18, 2026
6cc6fed
feat: update package.json
kkortes Jun 18, 2026
8f9b03c
add COMPILED badge to header on compiled branch
kkortes Jun 18, 2026
4a9f1de
make COMPILED badge gold
kkortes Jun 18, 2026
ba8321b
fix
kkortes Jun 18, 2026
9e6f417
compiled specific code
kkortes Jun 18, 2026
f5f1f6f
Bump @ape-egg/vibe to ^2.1.6
kkortes Jun 19, 2026
4e42e92
Merge branch 'feat/improve-compiled-battleborn-brawlers' into compile…
kkortes Jun 19, 2026
5910ddf
fix
kkortes Jun 19, 2026
1c40814
chore(release): v0.1.6
kkortes Jun 19, 2026
adb35de
removed compiled
kkortes Jun 19, 2026
0751fe2
test
kkortes Jun 19, 2026
41c2c00
fix
kkortes Jun 19, 2026
559c75a
test
kkortes Jun 19, 2026
8443baa
test
kkortes Jun 19, 2026
f9343c1
fix
kkortes Jun 19, 2026
fef3acd
fix
kkortes Jun 19, 2026
55bfc3e
test
kkortes Jun 19, 2026
eff47e8
test
kkortes Jun 19, 2026
7288692
fix
kkortes Jun 19, 2026
ba0184f
fix
kkortes Jun 20, 2026
7c0992b
Replace mugshot crops with focal-point Mugshot component
kkortes Jun 20, 2026
97ef6f7
vibe bump 2.1.9
kkortes Jun 20, 2026
1d641d8
Add paginated release notes modal, fix potion sfx volume
kkortes Jun 21, 2026
53ac842
Adopt Element Symbol Split equipment link, whiten tooltips, add color…
kkortes Jun 21, 2026
86c521d
Add seasons, season pass, login redesign, logo, and icon fixes
kkortes Jun 22, 2026
49d95f3
fix
kkortes Jun 22, 2026
15437ae
Rework potions: medicum brew bar, experience icon, card-hand fix
kkortes Jun 22, 2026
ffd5128
Fix compiled DnD, medicum brewer, duel cap, heirloom gating, icons
kkortes Jun 22, 2026
7ddcd6a
Redirect out-leveled arena fight to /the-arena on reward claim
kkortes Jun 22, 2026
1c934c0
Add Palaestra training, drop inventory row selection
kkortes Jun 22, 2026
e39c989
Bump vibe to 2.1.13, inline equipment row bindings
kkortes Jun 22, 2026
b877f17
Add status tuples, tolerance modifier, and ability SFX
kkortes Jun 23, 2026
80a3875
Add escalating enemy stat scaling, split brew/train timers
kkortes Jun 23, 2026
f92e3a8
Add Battle Pass WIP placeholder, bump vibe to 2.1.16
kkortes Jun 23, 2026
4d0c3e3
Fix brew timer stacking, refund retired gear, tooltip mask, ability copy
kkortes Jun 23, 2026
6428f4a
Fix scaling modal enemy curves, default foe/brawler selection
kkortes Jun 24, 2026
34419d6
Rename demoralizingShout SFX to bling, wire to Riposte
kkortes Jun 24, 2026
f36a01f
Add seeded seasonal arena, count-scaling, and arena portrait redesign
kkortes Jun 24, 2026
ee8c36d
Add crystal currency, gradient stat icons, and reward tooltips
kkortes Jun 24, 2026
117455b
Restore stunned status icon in Iconice
kkortes Jun 24, 2026
e7c314e
Match filter bar to basic-equipment color, neutralize theme toggle icon
kkortes Jun 24, 2026
6009597
Extract shared components and dedupe icon-cell tooltips
kkortes Jun 25, 2026
d2e7cfb
Unify key actions in boot, free tester potions, fix coin flash
kkortes Jun 25, 2026
e5321b3
Refine modals, sound toggle, equipment catalog, secondary hover
kkortes Jun 25, 2026
9ea38d0
Recolor modal frames, dialog back chevron, fix ability tooltip
kkortes Jun 25, 2026
b404c4d
Add PVE loot drops, materials, equipment element arrays, route renames
kkortes Jun 26, 2026
f2ef188
Add Mend cleanse ability and spiderling Skewer rotation
kkortes Jun 26, 2026
d338c9b
Add account statistics, granular save diff, and stats page
kkortes Jun 26, 2026
02bf6dc
Add loot tables, essences, and signature gear across all PvE fights
kkortes Jun 26, 2026
cbc7fe2
Fix compiled dev server crashing on transient build errors
kkortes Jun 26, 2026
b7d8cd5
Add achievements design-sandbox page and DevBar link
kkortes Jun 27, 2026
8a92037
Make worktrees resolve dev.sh and provision the server subpackage
kkortes Jun 27, 2026
d77e1e9
Make the compiled frontend the default launch config
kkortes Jun 27, 2026
ffa1234
Merge branch 'claude/jovial-brattain-524aab' into game/battleborn-bra…
kkortes Jun 27, 2026
32ba2db
Show worktree name as a tester-only link in the header
kkortes Jun 27, 2026
60a061d
Merge pull request #43 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 27, 2026
f158fef
Reuse the shared Dialog modal frame for the Season modal
kkortes Jun 27, 2026
0d8d301
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 27, 2026
80c73ac
Merge pull request #44 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 27, 2026
753fb84
Show BLOCKED floater and raise-in shield on successful block
kkortes Jun 27, 2026
dbb5c06
Merge pull request #45 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 27, 2026
544136f
Fix luck stats: dot-free tier keys, primitive leaves, crystals /100
kkortes Jun 27, 2026
ed63751
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 27, 2026
697e6c4
Merge pull request #46 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 27, 2026
743fc09
Add CSS hot-swap to compiled dev loop; exclude vibe HMR dep
kkortes Jun 27, 2026
caa88cf
Merge pull request #47 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 27, 2026
5dcf884
Fix dev.sh resolution in main checkout (relative --git-common-dir)
kkortes Jun 27, 2026
91555f1
Bump @ape-egg/vibe to ^2.1.20
kkortes Jun 27, 2026
b37dd90
Fix /_internal/sounds: resilient manifest load + .wav MIME in compile…
kkortes Jun 27, 2026
9f2b727
Merge pull request #48 from kkortes/claude/suspicious-hypatia-8df6ce
kkortes Jun 27, 2026
03dce5c
Add achievements system, center reveal, and dark/light banners
kkortes Jun 27, 2026
41ef9b1
fix
kkortes Jun 27, 2026
14258f9
Merge branch 'game/battleborn-brawlers' of github.com:kkortes/webdev-…
kkortes Jun 27, 2026
3f89e58
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 27, 2026
6be5b70
Merge pull request #49 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 27, 2026
cd77ad6
Merge branch 'game/battleborn-brawlers' of github.com:kkortes/webdev-…
kkortes Jun 27, 2026
cef3742
Add Brog/Grukk blacksmith gear, material-cost system, and new abilities
kkortes Jun 27, 2026
50ebe5a
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 27, 2026
e1fed10
Merge pull request #50 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 27, 2026
13b68aa
Play Hammer Of Fire SFX on achievement reveal
kkortes Jun 27, 2026
37322b6
Merge branch 'feat/more-improvements' into claude/jovial-brattain-524aab
kkortes Jun 27, 2026
191e25a
Redesign Adrenaline as heal+mitigation channel; rename Hamstring to D…
kkortes Jun 27, 2026
0dffbe8
Merge pull request #51 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 27, 2026
db70096
fix
kkortes Jun 27, 2026
81cce44
fixed icons
kkortes Jun 27, 2026
c53a9a6
Tune achievements, boss loot, XP curve, locked-card contrast, earth SFX
kkortes Jun 28, 2026
7169d08
Fix slot label, dismantle value, brewer save, ability filter, chainLink
kkortes Jun 28, 2026
2a87a32
Soften cramped tooltip cursor cutout to a dim instead of a hole
kkortes Jun 29, 2026
1b1070d
Merge remote-tracking branch 'origin/feat/more-improvements' into cla…
kkortes Jun 29, 2026
fb834f5
Merge pull request #52 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 29, 2026
9af4f5d
Add Wide Swing AoE ability for Denea with fast end-of-cast spin
kkortes Jun 29, 2026
82c50c8
Merge pull request #53 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 29, 2026
aa0266e
Rebalance vendor gear and accessories; fix retire, armory, tooltips
kkortes Jun 29, 2026
a429b95
Add allTolerances icon, fix dwarf dodge chance bucket
kkortes Jun 30, 2026
95593e2
Tune goblin critical chance and damage
kkortes Jun 30, 2026
5e1e480
Nerf Buckler block, Flanged Mace armor pen, Berserker's Charm
kkortes Jun 30, 2026
a39a6e1
Add team labels to combat with reusable arc/name component
kkortes Jun 30, 2026
450d925
Merge remote-tracking branch 'origin/feat/more-improvements' into cla…
kkortes Jun 30, 2026
bb7dc0b
Merge pull request #54 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 30, 2026
44b5a1c
Set season downtime to 0
kkortes Jun 30, 2026
cd1fe3b
Add teamplay combat, viewer-relative rotation, and i18n server errors
kkortes Jun 30, 2026
c5f417d
Merge remote-tracking branch 'origin/feat/more-improvements' into cla…
kkortes Jun 30, 2026
38b9d29
Merge pull request #55 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 30, 2026
7a0597a
Tilt combat ring into an ellipse; combatants and labels follow
kkortes Jun 30, 2026
df64ec3
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 30, 2026
6161d0f
Apply ring tilt at display-time so it composes with viewer rotation
kkortes Jun 30, 2026
dea2ac2
Make ring tilt a per-combat perspectiveEnabled flag with preview switch
kkortes Jun 30, 2026
ed8c9d7
Scale combatants by ring depth when perspective is enabled
kkortes Jun 30, 2026
beaf59b
Tilt ring further; fade glass card alpha by depth (0.2 floor)
kkortes Jun 30, 2026
ec423f6
Fade card backdrop-blur by depth: ~0 glass at front, full at back
kkortes Jun 30, 2026
7470251
Give outer team-label ring its own upright tilt (badges above far, be…
kkortes Jun 30, 2026
6fdd0f1
Tilt outer label ring slightly more (0.72)
kkortes Jun 30, 2026
892fff0
Diagonal 4-team layout in perspective (player at 225, X instead of +)
kkortes Jun 30, 2026
c8f7407
4-team layout: player bottom-left; depth cues use rotated y
kkortes Jun 30, 2026
a47e7f7
Apply diagonal ring offset to any team count divisible by 4
kkortes Jun 30, 2026
1a6f219
Ring offset: straddle centre evenly for any multiple of 4 (90 - 180/t…
kkortes Jun 30, 2026
e4689f3
Seat player at rotation/2 offset (lower-left): 315 for 4 teams, 292.5…
kkortes Jun 30, 2026
1fdfb7d
Apply multiple-of-4 ring rotation in both perspective and flat modes
kkortes Jun 30, 2026
23b6e52
Merge pull request #56 from kkortes/claude/peaceful-colden-19ad82
kkortes Jun 30, 2026
48a3b85
Show effect percentages in ability descriptions; armory tweaks
kkortes Jun 30, 2026
d3f448a
Re-query combat preview arena each fit to survive Vibe re-hydration
kkortes Jun 30, 2026
23034af
Merge branch 'staging/more-improvements' into game/battleborn-brawlers
kkortes Jun 30, 2026
86a275a
Add bot seeding, admin page, env-driven roles, armory/teamplay polish
kkortes Jun 30, 2026
a03a06a
Bump server async-await-websockets to ^3.1.0
kkortes Jun 30, 2026
dad4d47
Seed bots in-process from admin event (drop fragile subprocess)
kkortes Jun 30, 2026
fcf766f
Add teamplay pagination, refactor game state, combat fit scaling
kkortes Jun 30, 2026
66969cc
Add team badges and split result layout for 3+ team fights
kkortes Jun 30, 2026
8d4275c
Refine teamplay lobby controls and combat overlay teardown
kkortes Jun 30, 2026
5d26141
Add Stylecheat tabs component; apply on teamplay and armory
kkortes Jun 30, 2026
81aea4f
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jun 30, 2026
3a6d0b3
Merge pull request #57 from kkortes/claude/jovial-brattain-524aab
kkortes Jun 30, 2026
e463bd6
Source teamplay names from data-doc; fix bot health and split result …
kkortes Jul 1, 2026
ed9c7c6
Rebuild post-fight overlay as Heraldic Banner with stepped reveal
kkortes Jul 1, 2026
2f8f264
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jul 1, 2026
80aae39
Merge pull request #58 from kkortes/claude/jovial-brattain-524aab
kkortes Jul 1, 2026
6454141
Add native Table element; extract combat-result helpers
kkortes Jul 1, 2026
9ef48be
Merge branch 'staging/more-improvements' into claude/jovial-brattain-…
kkortes Jul 1, 2026
c350e9b
Reorganize DevBar columns; drop unused internal design pages
kkortes Jul 1, 2026
d66dc9f
Fix teamplay fight bar, armory table, escape, reward banner, dev reload
kkortes Jul 1, 2026
246961a
Add claim press-pop, level-card tiering, and premium disabled shadow
kkortes Jul 1, 2026
8a12c11
Merge remote-tracking branch 'origin/game/battleborn-brawlers' into c…
kkortes Jul 1, 2026
5b68ce5
Merge pull request #59 from kkortes/claude/jovial-brattain-524aab
kkortes Jul 1, 2026
d4185b2
Polish armory tables, teamplay UI, and add combat perspective toggle
kkortes Jul 1, 2026
64af1b8
Merge branch 'staging/more-improvements' into game/battleborn-brawlers
kkortes Jul 1, 2026
26c7550
Tighten ability inventory height and teamplay hover accent
kkortes Jul 1, 2026
dffb1c0
Rework progression XP bar and key combat labels/split to accounts
kkortes Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "Battleborn Brawlers Compiled (Frontend)",
"runtimeExecutable": "bun",
"runtimeArgs": ["run", "dev:compiled"],
"port": 5000,
"autoPort": true
},
{
"name": "Battleborn Brawlers (Frontend)",
"runtimeExecutable": "bun",
"runtimeArgs": ["run", "dev"],
"port": 5000,
"autoPort": true
},
{
"name": "Battleborn Brawlers (Backend)",
"runtimeExecutable": "bun",
"runtimeArgs": ["--cwd", "server", "--watch", "--env-file=.env", "index.js"],
"port": 1337,
"autoPort": false
}
]
}
14 changes: 14 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/setup-worktree.sh\""
}
]
}
]
}
}
12 changes: 12 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh
files=$(git diff --cached --name-only --diff-filter=ACMR)
[ -z "$files" ] && exit 0

git diff --cached --name-only --diff-filter=ACMR -z | xargs -0 bunx prettier --write --ignore-unknown --log-level=warn
git diff --cached --name-only --diff-filter=ACMR -z | xargs -0 git add

# Keep static/images/*.webp current with the /images masters (regenerate changed,
# prune orphans) and stage them — so committed art always ships, even with no dev
# server or local build having run.
bun scripts/images.js
git add -A static/images
28 changes: 19 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
node_modules

# Output
.output
.vercel
/.svelte-kit
/build
dist
compiled

# OS
.DS_Store
Thumbs.db

# Env
.env
.env.*
!.env.example
!.env.test

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.env*.local

# Logs
*.log

# Editor
.vscode
.idea

# Claude
.claude/*
!.claude/launch.json
!.claude/settings.json

# Stuff
_potential
_unused
_unused

# Test artifacts
test-results
static/audio/Imported Assets
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.0
24.12
13 changes: 13 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules
dist
build
.vercel
.output
test-results
bun.lockb
.env*
.claude/settings.local.json
static
*.svg
_potential
_unused
5 changes: 1 addition & 4 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"useTabs": false,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
"plugins": ["@ape-egg/prettier-plugin-vibe"]
}
1 change: 1 addition & 0 deletions .vercelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/images
96 changes: 96 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Battleborn Brawlers

The world's websites are overengineered. It doesn't have to be that way. Keep it simple Claude.

Strategy auto-battler. Currently a Multi-Page App with filesystem routing — `pages/x.html` serves `/x`, and a `$param` segment is dynamic (`pages/the-arena/$id.html` serves `/the-arena/:id`). **Subject to change** — could become an SPA later, so don't lean on MPA assumptions in feature code. The game must work responsively down to ~360px wide; reach for Stylecheat's three media queries (`sm:` ≤768px, `md:` 768–1024px, `lg:` >1024px) before any custom `@media`.

Open work — missing assets, content, and roadmap items — lives in [`TODO.md`](TODO.md). Log new gaps there as you hit them.

## Stack

- **Runtime**: Vibe (`@ape-egg/vibe`) — runtime-first reactive framework
- **CSS**: Stylecheat (hybrid build) — attribute-based CSS framework. We use `ChromeOnlyModifiers.css` (the `[g] { gap: calc(attr(g type(<number>)) * var(--unit)); }` form), **not** `Modifiers.css` (the `g-4`/`p-2` form).
- **Dev server**: Vite via `vite-plugin-vibe` for HMR. The `mpa-routes` plugin in `vite.config.js` derives routes from the `pages/` tree (a `$param` segment is dynamic, e.g. `pages/the-arena/$id.html` → `/the-arena/:id`, `page.params.id`). It resolves URLs in dev and injects each dynamic page's route template as `window.__ROUTE__` for `boot.js` — no generated file. For prod, add a matching `vercel.json` rewrite by hand when you add a dynamic page (Vercel reads `vercel.json` before it builds).
- **Vibe source**: Symlinked from `/Users/kortes/Projects/webdev/vibe/nodemodules/@ape-egg/vibe` (also `vite-plugin-vibe`).
- **`@ape-egg/async-await-websockets` source**: Symlinked from `/Users/kortes/Projects/webdev/async-await-websockets` (root + `server`).

## Dogfooding Vibe & Stylecheat

This project is the **primary dogfood** for `@ape-egg/vibe` and Stylecheat — both live as symlinks (see Stack). Things you'd expect from a mature framework (React/Vue/Svelte) may simply be missing in Vibe.

**When you hit a Vibe quirk or bug, STOP. Do not work around it.** No `setTimeout`, no `queueMicrotask`, no reaching into `window.__vibe*`, no wrapping in a manual signal. Workarounds in app code hide the gap and let it rot.

Instead, report it to me in this exact shape:

1. **The issue** — what Vibe does vs what you expected (one or two sentences).
2. **What you're trying to do** — the actual code you wanted to write, pasted inline as a code block, even if it doesn't run.
3. **Proposed solutions** — 1–3 options: the upstream fix in `webdev/vibe`, and (if applicable) a temporary local workaround. Be explicit that the upstream fix is the right one.

Frame it as **"Vibe is missing feature parity with modern frontend frameworks"** — because that's what most of these are. I decide whether we fix it upstream now or accept a workaround for this turn.

The same applies to Stylecheat (but rarer — Stylecheat is more mature).

## Game Server

The WebSocket backend lives in `server/`. Frontend integration:

- Connection lives on `$.socket` (see `js/connectSocket.js`); lifecycle is managed centrally — features should consume `$.socket` rather than open new connections.
- **Calling backend functions**: every file under `server/events/` is a server function, addressed by its path. Invoke from the client with `await $.socket.sendAsync('<dir>/<file>', payload)` — e.g. `events/user/authenticate.js` is `$.socket.sendAsync('user/authenticate', { token, … })`, `events/pvp/get-random-opponent.js` is `$.socket.sendAsync('pvp/get-random-opponent', …)`. New backend capabilities → drop a `.js` file in `events/<dir>/<file>.js` (server auto-registers) and call it the same way from the client.
- Game state seeded onto `$` flows from the server through `sendAsync` responses (mainly in `js/boot.js` and `js/connectSocket.js`). New event handlers should plug into the same place so reactive bindings stay coherent.
- Auth happens via `$.token`; the server validates it on the websocket handshake. Don't store credentials elsewhere.
- Constants (`js/constants/*`) must match the server's expectations — when the backend renames or adds a key, update the constant file in lockstep.
- Helpers belong in `/js/helpers.js`. Tiny utilities (formatters, parsers) should not get their own files.

## Guidelines for CLAUDE

`~` = enforce
`-` = avoid
`❌` = forbidden

### Testing

- `-` Playwright MCP, unless explicitly asked.
- `~` Prefer the Claude Desktop App Preview for in-app checks over the Playwright test browser.
- `~` Rely on manual browser testing — the user runs the game and reports issues; point out what to check.
- `~` **Preview throttles `requestAnimationFrame`.** The Claude Preview tab runs unfocused, so the browser throttles `rAF` to ~nothing — anything rAF-driven freezes (the combat replay sticks at `elapsedMilliseconds ≈ 166`, animations don't advance). `setTimeout`/`setInterval` still fire, so `preview_eval` and samplers work, but you can't observe rAF-driven UI. To un-throttle for a debugging session, shim it via `preview_eval` **before** the loop starts:

```js
window.requestAnimationFrame = (cb) => setTimeout(() => cb(performance.now()), 16);
window.cancelAnimationFrame = (id) => clearTimeout(id);
```

Then trigger the fight/animation and sample with a `setInterval`. The shim is ephemeral page state (gone on reload), so re-apply it after each reload. This is how the compiled-only "status chip stuck at 1" bug was finally observed.

### Markup & components

- `❌` HTML comments. The only HTML "comments" allowed are Vibe directives (`<!-- if -->`, `<!-- else -->`, `<!-- /if -->`, `<!-- each -->`, `<!-- /each -->`) — reactive control flow, not comments. Use JS `// TODO:` for "do later".
- `❌` `<div>`. Use semantic/custom element names: `<page-home>`, `<fight-row>`, `<ability-cell>`, `<xp-bar>`, `<coin-stack>`, etc.
- `❌` `class=""`. Exception: `<a class="button">` to give a tag a different visual treatment (Stylecheat keys some looks off `class`).
- `❌` `style=""`. Set CSS custom props via `<element attr="@[value]">`; only acceptable for unavoidable cases like tooltip absolute positioning.
- `-` `data-*` prefix. Use plain attributes — CSS `chip[stunned]`, HTML `<element @[status]>`. Exception: genuine HTML data semantics like `data-src`.
- `❌` `@[…]` in an **eager-loading URL attribute** (`<img src>`, `<video src>`/`<source>`, `poster`, `srcset`, preloaded `href`). In runtime mode the page ships the raw `@[…]` literal and the browser's preload scanner fetches it _before_ Vibe hydrates → 404 (e.g. `/static/images/races/`, `/@[cutscene…]`). The browser ignores `data-src`, so bind there instead: `<img data-src="/static/images/races/@[image]">` / `<video data-src="@[…]">`. The sync loop in [`js/boot.js`](js/boot.js) (`img[data-src], video[data-src]`, runs on every `afterUpdate`) copies `data-src` → `src` after hydration, skipping unresolved `@[…]` and filename-less paths. The clean fix is upstream — Vibe's **compiled (hyperspeed)** mode pre-renders values so no raw `@[…]` reaches the browser — but until pages are compiled, `data-src` is the convention.
- `~` Reuse the wrapper element's name for inner pieces — `<tooltip>`/`<tooltip-content>`/`<tooltip-title>`, `<combatant-card>`/`<combatant-header>`/`<combatant-name>`.
- `~` Page structure: `<script type="module">` at top, `<page-xxx>` wrapper, `<style>` at bottom.
- `~` Call functions bare from markup: `onclick="fn()"`, never `onclick="window.fn()"`.

### Styling & CSS

- `~` Prefer Stylecheat attributes (`g="4"`, `p="2"`, `vertical`, `primary`, `absolute`, `flex`, `down`, …) over hand-written CSS. Use ChromeOnly forms — `g="4"`, not `g-4`.
- `~` Local component styles go in a `<style>` at the bottom of the file, scoped with `[component-name]` (or unscoped when the element name is already unique). Lift shared/theme styles into `css/index.css`.
- `~` `attr()` is Stylecheat-only. For attribute-driven custom values, set a `--x` custom prop via a Vibe binding + a one-line rule.
- `-` `z-index`. Stacking should fall out of source order, `position`, and stacking contexts. Reorder the DOM first; in flex/grid use `order: -1` (see `css/stylecheat.css` ~line 1989). Last resort only: a named `var(--z-…)` token, and ask first.
- `❌` Hex colors outside `css/index.css`. Always `var(--color-name)`; add the var to `index.css` first if it's missing.
- `❌` `rem`, and raw `px` greater than `1px`. Use `calc(var(--unit) * N)`.

### Reactive state (Vibe)

- `~` Global state via `$` (not `window.$`). Component-local state: `const id = component(state); const s = $[id];`.
- `❌` Touching `window.__vibe*` internals (`__vibeComponents`, `__vibeGlobalState`, `__vibeManifest`, …). If something seems to need them, that's a missing public API → fix it upstream in `webdev/vibe`.
- `~` Boolean attributes: a pure `@[expr]` on a non-`data-*`/`aria-*`/`on*` attribute becomes a real boolean attribute (set when truthy, removed when falsy). `<modal-root open="@[when]">` + CSS `modal-root[open]` / `:not([open])` works directly.
- `~` Name-binding: when an attribute name equals the binding leaf (`name="@[ability.name]"`), use `<element @[ability.name]>` — same pattern as `<icon @[ability.icon]>`.
- `❌` Baking a loop-derived value into a handler with `@[…]`. A `@[…]` span is stringified once at hydrate, so `@[idx]`/`@[item.x]` goes stale on reorder/removal (this is how `equipItem($.inventory[@[idx]])` broke). Reference the loop alias bare — `onclick="equipItem(item)"` — and read `$.state` live inside the handler. The only `@[…]` that belongs in a handler is component-local `this.X`.

### Files

- `~` Every file ends with a trailing newline.
- `~` Imports: package imports first, then relative project imports.
80 changes: 65 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
## My personal repo
# Battleborn Brawlers

This repo is a work in progress and is currently my personal thing. Feel free to fork or ask questions about it, but expect things to change drastically.
Strategy auto-battler — a per-game branch of the [`webdev-game-stack`](https://github.com/kkortes/webdev-game-stack) monorepo

## Information

This is a highly opinionated monorepo for game dev using web tech.

The stack is:

- `Svelte` for frontend (https://svelte.dev)
- `Vibe` for frontend (runtime-first reactive framework via `@ape-egg/vibe`)
- `Stylecheat` for styling (attribute-based CSS framework)
- `Vite` + `vite-plugin-vibe` for dev server / HMR
- `Bun` for backend (https://bun.sh)
- `MongoDB` for database (https://www.mongodb.com)

## Run the client locally

```
nvm use
bun install
bun dev
```

The dev server is reachable both at `http://localhost:<port>` (printed on start) and at `https://webdev-game-stack.test` via the local Caddy proxy.

## Run the server locally

`touch .env` and add:
`touch server/.env` and add:

```
PORT=1337
Expand All @@ -34,9 +35,9 @@ PASSWORD_RESET_HASH=<custom_hash>
```

```
cd svelte-game-server
npm install
npm run dev
cd server
bun install
bun run dev
```

## Features
Expand All @@ -45,13 +46,62 @@ npm run dev
- ✅ Account log in
- ✅ Account creation
- ✅ Account password recovery
- ✅ Notification center
- ✅ Render backend hosting setup (https://render.com)
- ✅ Vercel frontend hosting setup (https://vercel.com)
- ✅ Tailwind CSS for styling (https://tailwindcss.com)
- ✅ Vibe + Stylecheat front-end (formerly Svelte + Tailwind)

## Code base quirks
## Combat stats budget

Source of truth for balancing races, equipment, racial bonuses, and (eventually) player-allocable specs. Pricing is **linear — no diminishing returns, no soft caps**.

**Baseline anchor:** `1 spec point = 2 damage = 4 health`

### Flat stats — what 1 spec point buys

Armor in this table assumes the **flat-reduction model**: each point of armor subtracts 1 damage from every incoming hit (clamped at 0). It does not deplete.

| Stat | 1 spec point = |
| -------------------------------------- | --------------------------------------------- |
| Health (`maxHealth`) | +4 HP |
| Armor (`maxArmor`) | +1 armor (flat reduction per hit) |
| Damage (`damage`) | +2 damage |
| Critical Chance (`criticalChance`) | +1% |
| Critical Damage (`criticalDamage`) | +10% |
| Block Chance (`blockChance`) | +1% |
| Dodge Chance (`dodgeChance`) | +1% |
| Magic Chance (`magicChance`) | TBD — mechanic pending |
| Elemental Resistance (`resistances.*`) | +4% (reduces incoming damage of that element) |

### Modifier stats — what 1 spec point buys

- `.env (development) & .env.production (production)` are injected into `src/constants/ENV_VARS.ts`. Trying to parse `import.meta.X` won't work in Svelte files, due to vite crashing when there is CSS in the files that they parse.
Modifiers are % multipliers in `combatStats.modifiers`. Rates below are pegged to default base values so the EV roughly matches the flat-stat table.

| Modifier | 1 spec point = |
| ---------------------- | ------------------------------------------------------- |
| `modifiers.maxHealth` | +15% |
| `modifiers.maxArmor` | +10% |
| `modifiers.damage` | +25% |
| `modifiers.resistance` | +2% (scales `wounded`/`concussed`/`exposed` thresholds) |

### Rules

- Linear pricing only. Stats must be honest and easy for the player to calculate.
- Unimplemented stats (currently `magicChance`) don't render in any UI until they have gameplay.
- When adding a new stat, give it a row here _before_ it ships. If it can't be priced linearly, it doesn't ship.
- Racial bonuses, equipment rolls, and spec choices all draw from the same currency — this table is the contract.

### Cost & the coin economy

Because stat scaling is linear, equipment doesn't differentiate by stat _shape_ — a higher-level piece is simply more of the same (e.g. armor = its level, so a higher-level armor is a strict upgrade of a lower one). The differentiator is **coin cost**, spent against a deliberately scarce economy: a player has roughly **25 coins total by level 25, shared across all 6 characters**. You can't gear everyone in top equipment — every purchase is a trade-off.

So when pricing current and future equipment:

- **Cost is the balancing lever, not stats.** A strictly-better item must cost proportionally more coins; price is what gates power, not stat complexity.
- Cheap, low-level gear stays relevant as the affordable pick when coins are tight.
- The only stat-shape trade-off we currently make is **heavy armor** (`+10` armor for `−40%` hit chance). Everything else competes purely on cost-vs-power along the linear curve.

## Code base quirks

- This repo utilizes `sveltekit-autoimport` (https://github.com/yuanchuan/sveltekit-autoimport) hence some `.svelte` and `.js` imports seem to magically appear out of nowhere. See `vite.config.js` to see what's going on.
- Routing is currently MPA-flavored, filesystem-driven by the `mpa-routes` plugin in `vite.config.js`: `pages/x.html` serves `/x`, and a `$param` segment is dynamic (`pages/the-arena/$id.html` → `/the-arena/:id`). It resolves URLs in dev and injects each dynamic page's route as `window.__ROUTE__` for `boot.js`; in prod, a dynamic route needs a matching `vercel.json` rewrite, added by hand. Subject to change — could become an SPA later, so feature code shouldn't lean on MPA assumptions.
- Vibe is symlinked from `/Users/kortes/Projects/webdev/vibe` for live editing during development. Production builds resolve normally from npm.
- Global reactive state lives on `$` (no `window.` prefix). Component-local state goes through `component(state)` + `$[id]`.
Loading