Spending and recovering shards: the transactions behind the forge console command.
Every transaction is a pure function of a Scriber.Game, returning {:ok, game, message}
with the wallet already debited or credited, or {:error, message} with the game
untouched. The message is player-facing text; callers print it and do no formatting of
their own. Nothing here touches disk — shards live in the game state.
Example
case Scriber.Forge.buy(game, "daggers") do
{:ok, game, message} -> {game, message}
{:error, message} -> {game, message}
end
Summary
Functions
The action for buying or selling what as the player typed it, or nil when the forge knows no such thing.
Every transaction as an action a Cauldron2D.World takes as input: :buy_power, :buy_mace, :sell_mace, ...
Run the transaction action stands for; :unknown for an action that is not one of actions/0.
Buy one thing, named by the string the player typed.
Everything the forge sells, priced for this game's current state.
Sell a weapon back for Scriber.Gear.resale/1 shards, removing it from :owned.
Types
@type outcome() :: {:ok, Scriber.Game.t(), String.t()} | {:error, String.t()}
Functions
The action for buying or selling what as the player typed it, or nil when the forge knows no such thing.
@spec actions() :: [atom()]
Every transaction as an action a Cauldron2D.World takes as input: :buy_power, :buy_mace, :sell_mace, ...
@spec apply(Scriber.Game.t(), atom()) :: outcome() | :unknown
Run the transaction action stands for; :unknown for an action that is not one of actions/0.
@spec buy(Scriber.Game.t(), String.t()) :: outcome()
Buy one thing, named by the string the player typed.
Accepts "power", "defence" (or "defense"), "patch", "fuse", "decoy",
"pulse", or anything
Scriber.Gear.parse/1 resolves to a weapon. On success the shards are debited and the
purchase applied: a weapon is added to :owned but not equipped, "power" and
"defence" raise :power_bonus / :defence_bonus by one, "patch" adds one to
:patches.
Returns {:error, message}, leaving the game unchanged, when the name is unknown, when the
name resolves to :unarmed, when the weapon is already owned, or when there are not enough
shards.
@spec listing(Scriber.Game.t()) :: [ %{key: String.t(), cost: pos_integer(), blurb: String.t()} ]
Everything the forge sells, priced for this game's current state.
Returns one map per item, in listing order: the four weapons from Scriber.Gear.purchasable/0,
then "power", "defence" and "patch". Each has :key (the string buy/2 accepts),
:cost in shards, and :blurb describing it. Upgrade costs reflect how many points the
player has already bought, and a weapon already owned says so in its blurb but is still
listed at full price.
@spec sell(Scriber.Game.t(), String.t()) :: outcome()
Sell a weapon back for Scriber.Gear.resale/1 shards, removing it from :owned.
what is resolved by Scriber.Gear.parse/1. Only weapons can be sold — power and defence
upgrades and patches cannot.
Returns {:error, message}, leaving the game unchanged, when the name is unknown, when it
resolves to :unarmed, when the weapon is not owned, or when it is the weapon currently in
hand.