Overview

TC-Bot is for players who treat Ark of War spreadsheets like sacred texts - except they would rather type /gearcheck in Discord than alt-tab back to a fifty-column workbook at midnight.

It is a single-package Discord bot, not a monorepo carnival. Commands live under src/commands/ grouped by concern (Ark of War calculators vs. small utility commands); the client loads them at startup after validating environment and warming the Google Sheet cache. Slash commands are the primary interface; legacy !tcmu exists for mopup embeds in a configured channel when you explicitly opt in, because migration is a process, not an event.

The bot is opinionated about data for sheet-backed features. Troop healing costs and iTS-style calculations lean on rows pulled from the Theorycrafters spreadsheet via a service account (client_secret.json) and a configurable TTL cache - fresh enough for theorycraft, bounded enough that Google API quotas stay boring. Startup validates sheet IDs and initializes the Sheets client (including a cache warm), so credential or permission problems fail the whole boot, not a single slash command. Gear check’s progression math is encoded in constants in code; healtroop and its additionally depend on parsed troop rows matching what theorycrafters expect from the workbook.

Like many long-lived community bots, TC-Bot delegates “who is allowed to run what” to Discord itself (guild deployment, channel permissions, optional message-command channel lock). Identity is not reinvented here; the complexity budget goes to correct modifiers, truncation limits on huge selects, and not double-posting when Discord delivers the same gateway event twice.

If you are explaining TC-Bot to a player, call it a pocket theorycrafter that answers stat questions in-thread. If you are explaining it to an engineer, call it a Discord.js v14 bot with readonly Sheets, SQLite-backed usage metrics, PM2-friendly hooks, and Vitest guarding the math. Both descriptions are true; they just emphasize different kinds of relief when your alliance asks for numbers five minutes before a hit.