Skip to content

Tower defense#427

Open
amilich wants to merge 42 commits intomainfrom
cursor/iso-tower-defense-game-4dc1
Open

Tower defense#427
amilich wants to merge 42 commits intomainfrom
cursor/iso-tower-defense-game-4dc1

Conversation

@amilich
Copy link
Owner

@amilich amilich commented Feb 17, 2026

Note

Medium Risk
Large feature addition touching client state management, local persistence, and a new API route; risk is mainly regressions in autosave/run lifecycle and simulation correctness rather than security-critical auth/data flows.

Overview
Adds IsoTower Defense as a new playable route (/tower) alongside IsoCity and IsoCoaster, including a full client UI (canvas grid renderer, sidebar/topbar, minimap, mobile toolbar, settings/stats dialogs) and tower interactions (place/upgrade/sell, targeting modes, wave controls).

Introduces tower-run persistence via TowerContext autosave + saved-run index management, plus a headless GET /api/tower-smoke simulation endpoint and a new npm run e2e:tower Puppeteer smoke test script. Documentation/navigation is updated to reference the third game, ESLint hook rules are downgraded to warnings, and dependencies are updated to include puppeteer-core (and a small Next.js patch bump in the lockfile).

Written by Cursor Bugbot for commit 5c96778. This will update automatically on new commits. Configure here.

cursoragent and others added 21 commits February 17, 2026 04:14
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
@assert-app
Copy link

assert-app bot commented Feb 17, 2026

Your pull request is now ready for review with Assert.

Open Review →


Stop waiting for your code to break. Ship with confidence using Assert.

@vercel
Copy link
Contributor

vercel bot commented Feb 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
isometric-city Ready Ready Preview, Comment Feb 17, 2026 7:06am

Request Review

cursoragent and others added 2 commits February 17, 2026 05:04
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

❌ Localization Failed

We encountered an issue while trying to localize your pull request.

🔍 What happened?

The Locadex i18n process encountered an unexpected error and could not complete successfully.

🛠️ Troubleshooting

  1. Check your repository structure - Ensure it follows supported formats
  2. Verify file permissions - Make sure the bot has access to create branches and PRs
  3. Try again - Close and reopen this PR to retry the localization

📞 Need Help?

If this issue persists, please contact our support team or check the Locadex documentation.


This is an automated message from the Locadex bot.

General Translation | Configure Locadex for iso-city

return {
tower: { ...tower, cooldownRemainingTicks: stats.fireCooldownTicks },
projectiles: [proj],
};
Copy link

Choose a reason for hiding this comment

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

Tower cooldown lasts one extra tick

Medium Severity · Logic Bug

tryFireTower() sets cooldownRemainingTicks to stats.fireCooldownTicks after firing, and the cooldown is only decremented on later ticks when the value is > 0. This makes the actual time between shots fireCooldownTicks + 1 ticks, which contradicts fireCooldownTicks being documented as “ticks between shots.”

Fix in Cursor Fix in Web

sellTower: (x: number, y: number) => boolean;
upgradeTower: (x: number, y: number) => boolean;
startWave: () => void;
};
Copy link

Choose a reason for hiding this comment

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

Ambiguous x/y numeric arguments in context

Medium Severity · Bugbot Rules

The context API exposes placeAtTile(x, y), sellTower(x, y), and upgradeTower(x, y) with multiple number arguments, which makes callsites prone to accidentally swapping x/y without TypeScript catching it. The team rule requires named-argument objects in this situation.

Additional Locations (1)

Fix in Cursor Fix in Web

Triggered by team rule: No ambiguous args at callsite in typescript

}: {
viewport: { offset: { x: number; y: number }; zoom: number; canvasSize: { width: number; height: number } } | null;
onNavigate: (x: number, y: number) => void;
}) {
Copy link

Choose a reason for hiding this comment

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

Ambiguous x/y args in minimap callback

Low Severity · Bugbot Rules

MiniMap exposes onNavigate: (x: number, y: number) => void, which has multiple number args that can be accidentally swapped at callsites without TypeScript catching it. The team rule requires passing a single object with named fields instead of positional numeric arguments.

Fix in Cursor Fix in Web

Triggered by team rule: No ambiguous args at callsite in typescript

Co-authored-by: Andrew Milich <milichab@gmail.com>
@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #434 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #434 for the changes.

Files internationalized (14)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 728 seconds.

General Translation | Configure Locadex for iso-city

Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #435 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #435 for the changes.

Files internationalized (17)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/saveUtils.ts: Added i18n code
  • src/games/tower/types/enemies.ts: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
  • src/games/tower/types/towers.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 1046 seconds.

General Translation | Configure Locadex for iso-city

@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #436 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #436 for the changes.

Files internationalized (17)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/saveUtils.ts: Added i18n code
  • src/games/tower/types/enemies.ts: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
  • src/games/tower/types/towers.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 876 seconds.

General Translation | Configure Locadex for iso-city

const gridX = (screenX / (TILE_WIDTH / 2) + screenY / (TILE_HEIGHT / 2)) / 2;
const gridY = (screenY / (TILE_HEIGHT / 2) - screenX / (TILE_WIDTH / 2)) / 2;
return { gridX: Math.floor(gridX), gridY: Math.floor(gridY) };
}
Copy link

Choose a reason for hiding this comment

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

Ambiguous coordinate parameters in helper functions

Low Severity · Bugbot Rules

New helper APIs like gridToScreen(gridX, gridY), screenToGridFloat(screenX, screenY), and distSq(ax, ay, bx, by) accept multiple number args where swapping order still typechecks. This makes it easy for future call sites to silently compute wrong coordinates/distances.

Additional Locations (2)

Fix in Cursor Fix in Web

Triggered by team rule: No ambiguous args at callsite in typescript

console.error('FAIL tower-e2e-smoke');
console.error(err);
process.exitCode = 1;
});
Copy link

Choose a reason for hiding this comment

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

Puppeteer browser left running on failures

Medium Severity · Logic Bug

If the smoke test throws before reaching await browser.close(), the bottom-level main().catch(...) handler sets process.exitCode but never closes the Puppeteer browser. This can leave a Chromium process running and keep the Node event loop alive, causing CI to hang or time out on failures.

Fix in Cursor Fix in Web

@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #437 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #437 for the changes.

Files internationalized (15)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/lib/initialState.ts: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 805 seconds.

General Translation | Configure Locadex for iso-city

@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #438 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #438 for the changes.

Files internationalized (16)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/types/enemies.ts: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
  • src/games/tower/types/towers.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 1022 seconds.

General Translation | Configure Locadex for iso-city

@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

Localization Complete! ✅

This PR has been successfully localized!

See #439 for the changes.

📋 Summary

Locadex has analyzed your changes and automatically localized your translatable content.

The localization changes have been automatically generated on a new branch. See #439 for the changes.

Files internationalized (16)
  • src/app/coaster/page.tsx: Added i18n code
  • src/app/page.tsx: Added i18n code
  • src/app/tower/layout.tsx: Added i18n code
  • src/app/tower/page.tsx: Added i18n code
  • src/components/tower/Game.tsx: Added i18n code
  • src/components/tower/MiniMap.tsx: Added i18n code
  • src/components/tower/Sidebar.tsx: Added i18n code
  • src/components/tower/TileInfoPanel.tsx: Added i18n code
  • src/components/tower/TopBar.tsx: Added i18n code
  • src/components/tower/TowerGrid.tsx: Added i18n code
  • src/components/tower/mobile/TowerMobileToolbar.tsx: Added i18n code
  • src/components/tower/panels/SettingsPanel.tsx: Added i18n code
  • src/components/tower/panels/StatsPanel.tsx: Added i18n code
  • src/games/tower/types/enemies.ts: Added i18n code
  • src/games/tower/types/game.ts: Added i18n code
  • src/games/tower/types/towers.ts: Added i18n code
Translation files updated (8)
  • 🇩🇪 public/_gt/de.json: Updated translation file
  • 🇪🇸 public/_gt/es.json: Updated translation file
  • 🇫🇷 public/_gt/fr.json: Updated translation file
  • 🇮🇹 public/_gt/it.json: Updated translation file
  • 🇯🇵 public/_gt/ja.json: Updated translation file
  • 🇧🇷 public/_gt/pt-BR.json: Updated translation file
  • 🇹🇷 public/_gt/tr.json: Updated translation file
  • 🇨🇳 public/_gt/zh.json: Updated translation file
Configuration files updated (2)
  • gt-lock.json: Updated the translation lockfile to add the latest changes
  • gt.config.json: Updated configuration with latest versionId

🔗 What happened?

  • 🔍 Analyzed your code changes for translatable content
  • 🔨 Internationalized your code changes
  • 🌐 Generated translations for supported languages
  • 🎉 Added localization commits directly to this PR

Localization completed by Locadex in 940 seconds.

General Translation | Configure Locadex for iso-city

Co-authored-by: Andrew Milich <milichab@gmail.com>
};

return { ...state, grid: nextGrid };
}
Copy link

Choose a reason for hiding this comment

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

Example towers sell for zero refund

Medium Severity · Logic Bug

Towers created in createTowerExampleState have tower.totalSpent set to 0, but sell refunds are calculated from totalSpent. This makes the example run’s towers effectively unsellable for money (refund shows as $0), which looks like a broken sell/refund system. The same pattern appears in /api/tower-smoke tower placement.

Additional Locations (1)

Fix in Cursor Fix in Web

Co-authored-by: Andrew Milich <milichab@gmail.com>
@locadex-agent
Copy link
Contributor

locadex-agent bot commented Feb 17, 2026

❌ Localization Failed

We encountered an issue while trying to localize your pull request.

🔍 What happened?

The Locadex i18n process encountered an unexpected error and could not complete successfully.

🛠️ Troubleshooting

  1. Check your repository structure - Ensure it follows supported formats
  2. Verify file permissions - Make sure the bot has access to create branches and PRs
  3. Try again - Close and reopen this PR to retry the localization

📞 Need Help?

If this issue persists, please contact our support team or check the Locadex documentation.


This is an automated message from the Locadex bot.

General Translation | Configure Locadex for iso-city

Co-authored-by: Andrew Milich <milichab@gmail.com>
Co-authored-by: Andrew Milich <milichab@gmail.com>
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

},
{ timeout: 45_000 },
wave0
);
Copy link

Choose a reason for hiding this comment

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

Wave wait logic misparses “N/FINAL”

Medium Severity · Logic Bug

The e2e smoke test’s wave-increment wait uses Number((textContent).replace(/[^0-9-]/g, '')), but the UI renders wave as "{stats.wave}/{FINAL_WAVE_NUMBER}". Stripping non-digits turns "3/20" into "320", so the wait condition can trigger incorrectly and make e2e:tower fail or become flaky.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

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

Quick review pass:

  • Main risk area here is data integrity, transaction boundaries, and backward-compatible persistence.
  • Good to see test coverage move with the code; I’d still make sure it exercises the unhappy path around data integrity, transaction boundaries, and backward-compatible persistence rather than only the happy path.
  • Before merge, I’d smoke-test the behavior touched by README.md, eslint.config.mjs, package-lock.json (+36 more) with malformed input / retry / rollback cases, since that’s where this class of change usually breaks.

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.

3 participants