- Hollowcrown: The Rift Between Worlds as its own seed (npm run seed:hollowcrown), built from the campaign book: pools, 58 monsters, 57 NPCs, 28 locations, 72 encounters with rewards, and DM notes. Shared seeding logic moved to prisma/seedCampaign.js. - What players can see: only encounters their own character is in; only the pool entries their character holds (plus starting options while building); only locations their character has been to; no invite code; no gold, inventory or money log of other players' characters. Socket events carry ids only and campaign rooms are members-only. - Encounters have a location; while one is in progress its characters are there, and visits are remembered. - Campaign setting to show players a health bar only for monsters and NPCs. - Initiative is entered as the d20 roll (1-20) and the bonus is added; players can enter their own character's roll. - Number fields enforce their limits when typing, and the API enforces the same limits. - Temp HP shows on HP bars and absorbs damage before real HP. - All packages at version 1.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 KiB
Weapons
How weapons work in this app: the campaign's weapon pool, how a character comes to hold a weapon, weapon levels, and how attack and damage numbers are worked out.
This describes the code as it stands. The formulas live in
backend/src/game/calculations.js; the built-in list is
backend/src/game/data/weaponsLibrary.js. Related: ITEMS.md,
SPELLS.md, CHARACTERS.md.
Contents
- The basics
- The weapon pool
- The built-in library
- Giving weapons to characters
- Weapon levels
- How damage grows
- Attack and damage numbers
- Starting weapons
- Weapons as rewards
- Permissions
- What is not modelled
- The complete weapon library
1. The basics
- Every campaign has its own weapon pool. A weapon exists in one campaign only.
- A character never owns a free-standing weapon: it holds a copy of a pool entry, with its own quantity, level and equipped flag.
- The DM runs the pool and decides who gets what. Players can only equip and unequip what they hold.
2. The weapon pool
The pool is the "Weapons Pool" card on the campaign page (DM only).
| Field | What it is |
|---|---|
| Name | Free text, up to 80 characters |
| Base damage | Dice such as 1d8 or 2d6 — the damage at the weapon's starting level |
| Damage type | Free text: slashing, piercing, fire… |
| Attack ability | Strength, Dexterity, or Finesse (whichever of the two is higher for the wielder) |
| Starts at level | 1 to 9. The lowest level this weapon can be (section 5) |
| Growth | Standard, Powerful or Legendary: how fast the dice climb per level (section 6) |
| Starting option | Whether a brand-new character may pick it in the builder (section 8) |
| Properties, range | Stored for library weapons (light, thrown, 20/60 ft…) but not shown or used anywhere |
- Adding: by hand with the "+ Add Weapon" form, or from the library.
- Changing: starting level, growth and the starting-option tick box can be changed in the table. Name, damage, type and ability cannot be changed on screen once created (the API accepts it); remove and re-add instead.
- Removing: the ✕ button. This takes the weapon away from every character holding it and off every encounter's reward list. There is no undo.
- The same weapon can be added twice; nothing stops duplicate names.
3. The built-in library
"📚 From Library" offers 37 standard weapons to copy into the pool:
| Category | Count | Examples |
|---|---|---|
| Simple melee | 10 | Club 1d4, Dagger 1d4, Mace 1d6, Spear 1d6 |
| Simple ranged | 4 | Shortbow, Light Crossbow, Dart, Sling |
| Martial melee | 18 | Longsword 1d8, Rapier 1d8, Greataxe 1d12, Greatsword 2d6 |
| Martial ranged | 5 | Longbow, Heavy Crossbow, Hand Crossbow |
A weapon added from the library arrives with starting level 1, Standard growth, and not ticked as a starting option. Change those in the table afterwards. Every library weapon is listed in section 12.
4. Giving weapons to characters
On a character's sheet, the DM picks a weapon from the pool and clicks Give.
- It arrives at the weapon's starting level, quantity 1, unequipped.
- Giving a weapon the character already holds adds to the stack; the stack keeps the level it has. A character holds one stack per weapon, so two copies of the same weapon at different levels is not possible.
- The DM can take a weapon away with ✕ on the sheet.
- The owning player ticks Equipped. Equipped is a label only: unequipped weapons still show their numbers, and nothing limits how many are equipped.
Passing a weapon on. A character's owner (or the DM) can give a held weapon to another character in the campaign from the "Give to Another Character" card on the sheet. Some or all of the stack moves: it leaves the giver and arrives with the recipient at the giver's level, unequipped. If the recipient already holds that weapon, their stack grows and keeps its own level. A recipient below the weapon's level holds it but cannot use it yet.
5. Weapon levels
This is a house rule of this app, not standard D&D.
- Each held copy has a level from 1 to 9. Two characters can hold the same weapon at different levels.
- Only the DM changes a copy's level, with the level picker beside it on the sheet. Each option shows the damage at that level.
- A copy can never go below the pool entry's starting level. Raising a pool entry's starting level lifts any copies below it and unequips them.
Who can use it. A character must be at least the copy's level:
| Character level | Can use weapons of level |
|---|---|
| 1 | 1 |
| 2 | 1–2 |
| 5 | 1–5 |
| 9 and above | 1–9 |
A weapon above its holder's level is still held, but it shows "Requires level N", cannot be equipped, and is left out of quick stats and encounters. If the DM levels a weapon past its holder, or lowers the character's level, it is unequipped automatically.
6. How damage grows
The dice in the pool are the damage at the weapon's starting level. Each level above that moves the dice up a fixed ladder, in the smallest steps dice allow:
| Rung | Dice | Average |
|---|---|---|
| 1 | 1d4 | 2.5 |
| 2 | 1d6 | 3.5 |
| 3 | 1d8 | 4.5 |
| 4 | 1d10 | 5.5 |
| 5 | 1d12 | 6.5 |
| 6 | 2d6 | 7 |
| 7 | 1d6+1d8 | 8 |
| 8 | 2d8 | 9 |
| 9 | 1d8+1d10 | 10 |
| 10 | 2d10 | 11 |
| 11 | 1d10+1d12 | 12 |
| 12 | 2d12 | 13 |
| 13 | 3d8 | 13.5 |
| … | adding a die each time the current dice max out |
Every rung is +1 average damage over the last, or +0.5 where a die is added.
Growth sets how many rungs a weapon climbs per level:
| Growth | Rungs per level | A 1d6 weapon at levels 1, 2, 3, 4 | At level 9 |
|---|---|---|---|
| Standard | 1 | 1d6, 1d8, 1d10, 1d12 | 2d10 |
| Powerful | 2 | 1d6, 1d10, 2d6, 2d8 | 1d10+2d12 |
| Legendary | 3 | 1d6, 1d12, 2d8, 1d10+1d12 | 4d12 |
A weapon with a higher starting level counts from there: a 2d6 greatsword that starts at level 3 with Standard growth is 2d6 at level 3, 1d6+1d8 at level 4 and 2d8 at level 5.
- At its starting level a weapon always shows its dice exactly as typed.
- Dice that are not on the ladder (
1d4+1,2d4+2) climb from the highest rung that is not stronger than them:2d4+2(average 7) continues from 2d6. - Dice the app cannot read (free text such as "special") never change.
7. Attack and damage numbers
| Number | Formula |
|---|---|
| Attack bonus | Ability modifier + proficiency bonus |
| Damage | The dice at the copy's level + ability modifier |
- The ability modifier is Strength, Dexterity, or the higher of the two for a Finesse weapon.
- The weapon's level changes the dice only, never the bonuses.
- Every character is treated as proficient with every weapon.
These numbers appear on the character sheet, in the quick-stats drawer, and on the character's card in an encounter.
8. Starting weapons
In the builder's equipment step a new character can pick weapons that are:
- ticked as a starting option in the pool, and
- starting level 1 (a new character is level 1).
Starting weapons and starting items share the campaign's "starting items" allowance. They arrive at level 1, unequipped.
9. Weapons as rewards
On an encounter the DM can line up a weapon as a reward, at a chosen level (not below its starting level) and quantity, and later award it to a character. Awarding adds it to what the character holds, exactly as giving it on the sheet would. See ENCOUNTERS.md.
10. Permissions
| Action | DM | Owning player | Other players |
|---|---|---|---|
| See the pool | Yes | Only what their own character holds, plus the starting options while they have a character to build | The same, for their own character |
| See the built-in library | Yes | No | No |
| Add, change or remove pool entries | Yes | No | No |
| Give a weapon from the pool, or take one away | Yes | No | No |
| Give a held weapon to another character | Yes | Yes | No |
| Change a held weapon's level or quantity | Yes | No | No |
| Equip or unequip | Yes | Yes, if the character can use it | No |
| See a character's weapons | Yes | Yes | Yes |
11. What is not modelled
- Weapon proficiency by class (everyone is proficient with everything)
- Properties: two-handed, versatile, light, reach, loading, thrown
- Range and ammunition
- Critical hits, advantage, and rolling the attack itself (use the dice roller)
- Magic bonuses such as +1 weapons (use a higher level or growth instead)
- Price and weight
12. The complete weapon library
Every weapon "📚 From Library" offers. Base damage is the damage at level 1. Properties and range are carried into the campaign but not shown or used.
This list is written from the app's own data by npm run docs:lists (in /backend). Re-run it after changing the data; do not edit the list by hand.
Simple Melee (10)
| Weapon | Base damage | Type | Attacks with | Properties | Range |
|---|---|---|---|---|---|
| Club | 1d4 | bludgeoning | Strength | light | — |
| Dagger | 1d4 | piercing | Strength or Dexterity (finesse) | finesse, light, thrown | 20/60 ft |
| Greatclub | 1d8 | bludgeoning | Strength | two-handed | — |
| Handaxe | 1d6 | slashing | Strength | light, thrown | 20/60 ft |
| Javelin | 1d6 | piercing | Strength | thrown | 30/120 ft |
| Light Hammer | 1d4 | bludgeoning | Strength | light, thrown | 20/60 ft |
| Mace | 1d6 | bludgeoning | Strength | — | — |
| Quarterstaff | 1d6 | bludgeoning | Strength | versatile (1d8) | — |
| Sickle | 1d4 | slashing | Strength | light | — |
| Spear | 1d6 | piercing | Strength | thrown, versatile (1d8) | 20/60 ft |
Simple Ranged (4)
| Weapon | Base damage | Type | Attacks with | Properties | Range |
|---|---|---|---|---|---|
| Light Crossbow | 1d8 | piercing | Dexterity | ammunition, loading, two-handed | 80/320 ft |
| Dart | 1d4 | piercing | Strength or Dexterity (finesse) | finesse, thrown | 20/60 ft |
| Shortbow | 1d6 | piercing | Dexterity | ammunition, two-handed | 80/320 ft |
| Sling | 1d4 | bludgeoning | Dexterity | ammunition | 30/120 ft |
Martial Melee (18)
| Weapon | Base damage | Type | Attacks with | Properties | Range |
|---|---|---|---|---|---|
| Battleaxe | 1d8 | slashing | Strength | versatile (1d10) | — |
| Flail | 1d8 | bludgeoning | Strength | — | — |
| Glaive | 1d10 | slashing | Strength | heavy, reach, two-handed | — |
| Greataxe | 1d12 | slashing | Strength | heavy, two-handed | — |
| Greatsword | 2d6 | slashing | Strength | heavy, two-handed | — |
| Halberd | 1d10 | slashing | Strength | heavy, reach, two-handed | — |
| Lance | 1d12 | piercing | Strength | reach, special | — |
| Longsword | 1d8 | slashing | Strength | versatile (1d10) | — |
| Maul | 2d6 | bludgeoning | Strength | heavy, two-handed | — |
| Morningstar | 1d8 | piercing | Strength | — | — |
| Pike | 1d10 | piercing | Strength | heavy, reach, two-handed | — |
| Rapier | 1d8 | piercing | Strength or Dexterity (finesse) | finesse | — |
| Scimitar | 1d6 | slashing | Strength or Dexterity (finesse) | finesse, light | — |
| Shortsword | 1d6 | piercing | Strength or Dexterity (finesse) | finesse, light | — |
| Trident | 1d6 | piercing | Strength | thrown, versatile (1d8) | 20/60 ft |
| War Pick | 1d8 | piercing | Strength | — | — |
| Warhammer | 1d8 | bludgeoning | Strength | versatile (1d10) | — |
| Whip | 1d4 | slashing | Strength or Dexterity (finesse) | finesse, reach | — |
Martial Ranged (5)
| Weapon | Base damage | Type | Attacks with | Properties | Range |
|---|---|---|---|---|---|
| Blowgun | 1 | piercing | Dexterity | ammunition, loading | 25/100 ft |
| Hand Crossbow | 1d6 | piercing | Dexterity | ammunition, light, loading | 30/120 ft |
| Heavy Crossbow | 1d10 | piercing | Dexterity | ammunition, heavy, loading, two-handed | 100/400 ft |
| Longbow | 1d8 | piercing | Dexterity | ammunition, heavy, two-handed | 150/600 ft |
| Net | - | special | Dexterity | special, thrown | 5/15 ft |