-
Notifications
You must be signed in to change notification settings - Fork 0
Builders
Generated from the thetowersdk repository. Edits made here are overwritten on the next push — change the source file instead.
Ready-made calculators. Each one pairs the maths in thetowersdk/mechanics with the things a tool
needs around it and never gets for free: a complete set of defaults, a description of every input,
normalisation of whatever half-filled state a form is in, and a result that says what it could not
work out.
import { labResearchCalculator } from 'thetowersdk/builders'
const result = labResearchCalculator.compute({ labName: 'Damage', targetLevel: 10 })
console.log(result.totalCoinCost, result.totalHours)
for (const note of result.notes) console.warn(note)compute takes a Partial on purpose — a form hands you half-filled state constantly, and a
calculator that throws or returns NaN on that pushes the problem back into the UI.
Render a form without knowing which calculator it is:
for (const field of labResearchCalculator.fields) {
// field.kind is 'number' | 'select' | 'boolean' | 'number-list'
}| Builder | Answers |
|---|---|
labResearchCalculator |
Coins and time to take a lab from one level to another |
workshopUpgradeCalculator |
Coins to move a workshop stat between two levels |
moduleCostCalculator |
Shards and coins to level a module, capped by its rarity |
ultimateWeaponCalculator |
Power Stones for an ultimate weapon stat |
uptimeCalculator |
What share of the time an ability is actually running |
guardianCalculator |
Bits for a guardian stat |
botUpgradeCalculator |
Medals for a bot stat |
enemyWaveCalculator |
Health and damage per enemy kind at a tier and wave |
damageReductionCalculator |
What reaches the tower after every mitigation layer |
assistModuleStonesCalculator |
Stones for an assist efficiency slot |
coinsPerKillCalculator |
What one enemy pays, all six bonus sources applied |
thornsCalculator |
Damage returned to an enemy on contact |
dissonanceCalculator |
The multiplier your tier personal bests apply to a stat |
enemyDropsCalculator |
Module drop chances, reroll shards, shatter shards |
innerLandMinesCalculator |
Mine damage, count, cooldown, and what charge time is worth |
CALCULATOR_BUILDERS is all of them, and findCalculatorBuilder(id) looks one up — enough to
build a calculator picker that needs no per-calculator code at all.
They wrap thetowersdk/mechanics rather than reimplementing it, so a correction to a formula
reaches every tool without anyone re-deriving it.
Every builder handles these the same way, so a number means the same thing whichever one produced it.
| Rule | How |
|---|---|
| A level is capped by its own catalog |
clampLevel(value, cap, fallback), where cap comes from the curve that stat actually uses |
| An open-ended quantity is bounded so the result stays finite |
clampMagnitude(value, fallback), bounded by MAX_INPUT_MAGNITUDE
|
| A level buys against the previous row |
costIndexForLevel(level) — buying level L reads entry L−1 |
| Anything only a formula bounds gets a named constant | e.g. MAX_MODEL_WAVE, where the wave curve stops producing a real number |
| Clamping is reported | the result's notes say what was clamped and to what |
Caps come from the data rather than a shared constant because the curves genuinely differ: workshop
Attack Speed prices 75 levels, Enemy Level Skip 60, Damage 400. Level indexing follows tower-oracle
workshop.upgradeTable: a cost row buys the next level, so entry L is what is charged at level L
and buying level L costs entry L−1.
Ids, slugs and level indices arrive from saves, from the community sheet, from URLs and from tool
arguments. Lookups keyed by them use own-key access (ownLookup) for records and a
bounds-and-integer check (atIndex) for arrays, so an unknown key returns undefined rather than
whatever sits on Object.prototype.
The reason it is a rule rather than a caution: record['constructor'] is the Object function and
record['toString'] is a function, and neither ?? nor || nor a truthiness check will reject one.
The fallback simply never fires, and a function travels on from a signature that promised a string.
Cost ladders are bounded the same way, by the table rather than by the caller: a level past the end of a curve is excluded rather than priced at zero.
Generated from TheTowerSDK — do not edit here. Docs and live demos: https://tmrxjd.github.io/TheTowerSDK/
- Quick Start
- Entry Points
- How It Fits Together
- Getting a Save File
- Reading a Save
- Reading The Community Wiki
- Formulas
- Builders
- Charts
- Effective Paths
- Examples
- Templates
- Building a Bot On This
- Google Sheets
- Desktop and Mobile
- Optional Add-ons
- Using It With An AI Agent
- Using Your Own Artwork
- Names And Acronyms
- Patch Notes
- Accuracy
- Versioning
- Where the Docs Live
- Contributing
- Credits
- License
Guides
Examples
- 01-browse-game-data.ts
- 02-read-a-save-file.ts
- 03-plan-upgrades-from-a-save.ts
- 04-generate-a-chart.ts
- 05-generate-a-cost-table.ts
- 06-read-the-community-wiki.ts
- 07-format-like-the-game.ts
- 08-build-a-calculator.ts
- 09-build-a-bot.ts
- 10-read-a-sheet.ts
- 11-build-a-knowledge-base.ts
- 12-show-module-and-card-art.ts
Templates