Scriber.Gear (Scriber v0.1.2)

Copy Markdown View Source

The weapon table: what the scriber can fight with, and what each costs.

A weapon is a plain map with the fields in t/0. Scriber.Game reads them like this:

  • hits — swings per attack; a later swing is skipped if an earlier one killed the target
  • power — replaces the attacker's own power for the roll
  • defence — the player's mitigation while holding it
  • pierce — armour the swing ignores
  • parry — probability in 0.0..1.0 of turning an incoming hit aside entirely
  • stun — probability in 0.0..1.0 that a hit costs the target its next action

Damage per swing is max(1, power + d4 - max(target_defence - pierce, 0) - 1), and armour applies to each swing separately, so a multi-hit weapon loses more to a heavily armoured target than a single-hit one of equal total power.

Every weapon costs the same; the choice is which, not how much. Upgrades to power and defence cost more the more of them have been bought.

Example

Scriber.Gear.fetch(:daggers).hits
#=> 2
Scriber.Gear.power_cost(2)
#=> 75

GEAR_DESIGN.md at the repository root records the modelling behind these numbers.

Summary

Functions

Every equippable name, including :unarmed. Order is unspecified.

The shard price of a weapon. The same 45 for every weapon.

The shard price of the next point of defence, given owned points already bought.

The weapon entry for name, with :name set on it.

The weapon name matching a string a player typed, or nil if none does.

The shard price of one patch.

The shard price of the next point of power, given owned points already bought.

The four buyable weapons, in the order the forge lists them. Excludes :unarmed.

What selling a weapon back pays: half its cost/1, rounded down.

The shard price of a fuse, a decoy or a pulse.

Types

name()

@type name() :: :unarmed | :two_hand | :shield | :daggers | :mace

t()

@type t() :: %{
  name: name(),
  label: String.t(),
  hits: pos_integer(),
  power: pos_integer(),
  defence: non_neg_integer(),
  pierce: non_neg_integer(),
  parry: float(),
  stun: float(),
  blurb: String.t()
}

Functions

all()

@spec all() :: [name()]

Every equippable name, including :unarmed. Order is unspecified.

cost(weapon)

@spec cost(name()) :: pos_integer()

The shard price of a weapon. The same 45 for every weapon.

defence_cost(owned)

@spec defence_cost(non_neg_integer()) :: pos_integer()

The shard price of the next point of defence, given owned points already bought.

Rises linearly: 30 * (owned + 1).

fetch(name)

@spec fetch(name()) :: t()

The weapon entry for name, with :name set on it.

name must be one of all/0; anything else raises a FunctionClauseError.

parse(text)

@spec parse(String.t()) :: name() | nil

The weapon name matching a string a player typed, or nil if none does.

The string is trimmed, downcased, and has - replaced with _ before it is matched against both the atom names and the labels, so "Sword+Shield" and "shield" both give :shield, and "two-hand" gives :two_hand.

patch_cost()

@spec patch_cost() :: pos_integer()

The shard price of one patch.

power_cost(owned)

@spec power_cost(non_neg_integer()) :: pos_integer()

The shard price of the next point of power, given owned points already bought.

Rises linearly: 25 * (owned + 1).

purchasable()

@spec purchasable() :: [name()]

The four buyable weapons, in the order the forge lists them. Excludes :unarmed.

resale(weapon)

@spec resale(name()) :: pos_integer()

What selling a weapon back pays: half its cost/1, rounded down.

tool_cost(tool)

@spec tool_cost(:fuse | :decoy | :pulse) :: pos_integer()

The shard price of a fuse, a decoy or a pulse.