const StatusMove, StatusRun, StatusDown, StatusHead
Target statuses a FIRE card may list (rule 13.6), as the letters of a card's status string.
Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.
Package engine is the pure, deterministic rules engine of a gunfight of two to four characters: plan parsing and vali...
Package engine is the pure, deterministic rules engine of a gunfight of two to four characters: plan parsing and validation, and the 5-segment resolution of a turn. It has no chain dependency so it can be unit-tested with gno test.
Target statuses a FIRE card may list (rule 13.6), as the letters of a card's status string.
Second-draw penalties.
Hand codes used in plan strings: 0 = gun hand, 1 = other hand, 2 = both hands; HandGround, "g" in a gun move, is the hex the character stands in.
Shoot options: what a Cock/Aim/Shoot does (11.3), or a Shoot (shoot or nothing). Aiming and shooting name their target (11.31): a hex of the aim zone ("5f:aim:A-F6", "7f:shoot:A-F6") or a character by seat ("5f:aim:@1", "7f:shoot:@1"). A shot at a hex hits the character standing there when it goes off, and is wasted otherwise.
Strength options (20.2): a STRENGTH adds to the penalties ("7b:damage", also a bare "7b", what a STRENGTH does when its use is not stated) or to the wielding factor ("7b:wield") of the Throw it is played on top of.
Card 7's STRENGTH adds 4 to the wielding factor or 2 to the penalties.
1const (
2 EvMove = "move" // From, To, Facing, Down, Action (Reason "stagger" when thrown by a hit)
3 EvTurn = "turn" // Facing, Action (Reason "stagger" when thrown by a hit)
4 EvFlip = "flip" // Down, Action (empty for a DROP penalty)
5 EvDelay = "delay" // N gained, Reason, Card drawn (0 for crawl), Result penalty, Endurance crossed off, Delay = running total once this card is counted
6 EvCancel = "cancel" // Action, Reason (To = the obstacle in the way for no_los)
7 EvDraw = "draw" // Gun moved from From (holster, a hand, or "ground" with N = its ground id) to To (a hand) and cocked, unless jammed (Result "jammed")
8 EvLoad = "load" // a shell loaded in the gun in both hands, N shells now, uncocked; Result "unjammed" when that completes a jammed gun
9 EvCock = "cock" // Gun cocked
10 EvUncock = "uncock" // Gun uncocked
11 EvAim = "aim" // N = AIM points after aiming, To = the hex they sit on, Target = the seat they follow (-1 for a hex)
12 EvLoseAim = "lose_aim" // Reason (To = the obstacle in the way for no_los)
13 EvNothing = "nothing" // a Shoot used to do nothing, or a shot held at a hex nobody stands in (Reason empty_hex, To = the hex) or at a target out of sight (Reason no_los, To = its hex, Target = its seat) or out of the fight (Reason out_of_fight, To = its hex, Target = its seat): keeps the aim
14 EvShot = "shot" // Card, Target = the seat shot at (whoever stood in the hex named, for a shot at a hex), To = the hex shot at, Hit (final location or Miss), Range, N = aim time, Reason "" | out_of_zone | misfire
15 EvThrow = "throw" // like a shot: Card, Target, To = the hex thrown at, Hit, Range, N = aim time, Chart, Status, Gun, GunID, Reason "" | out_of_zone; the weapon then lands (EvDropGun, Reason throw)
16 EvMalfunction = "malfunction" // Card, Result (no_effect, misfire, jams, explodes, no_penalty), Gun, GunID
17 EvWildShot = "wild_shot" // Gun went off without hitting anything: uncocked, one shell less
18 EvWound = "wound" // Player hit: Result = penalty kind (Kill, Stun...), N
19 EvDirection = "direction" // Card drawn as a direction card: To = its HEX line
20 EvDropGun = "drop_gun" // Gun fell from From (hand) to the hex To, N = its ground id; Reason throw for a thrown weapon landing, gun_move for one let go (10.22)
21 EvMoveGun = "move_gun" // a gun move (10.22): Gun moved from From (both hands) to To (a hand), as it was
22 EvPassOut = "pass_out" // end of turn: more delay than endurance two turns in a row
23 EvSeriousCheck = "serious_check" // end of showdown: Card, N = DELAY + SERIOUS points (4 kills)
24 EvVP = "vp" // end of turn: victory points (rule 15), N = points (< 0 for a loss), Reason = the award (VPSurvive...)
25 EvRunAway = "run_away" // the character moved off the map (15.5): From = the edge hex it left, Facing = the way it went, Action
26)Event kinds.
1const (
2 ReasonCrawl = "crawl" // moving while down (rule 9.2)
3 ReasonSprint = "sprint" // sprinting draws a delay card (rule 9.23)
4 ReasonLeap = "leap" // leap/drop draws two delay cards (rule 9.4)
5 ReasonOccupied = "occupied" // ending a move in an occupied hex (rule 9.24)
6 ReasonFence = "fence" // moving or staggering across a fence (rule 35.2)
7 ReasonObstacle = "obstacle" // moving or staggering onto or off an obstacle (rule 36.4)
8 ReasonDrop = "drop" // a DROP penalty draws three delay cards (rule 14.11)
9 ReasonStun = "stun" // a STUN draws wound cards (14.11)
10 ReasonLight = "light" // a LIGHT draws fatigue cards (14.11)
11 ReasonSerious = "serious" // fatigue cards at the start of the turn (14.12)
12 ReasonLeg = "leg" // fatigue cards per hex moved upright (14.12)
13 ReasonTime = "time" // not executed by the end of segment 5 (rule 7.53)
14 ReasonNoGun = "no_gun" // no gun in the box the action needs (11.3); a gun move of a gun the character no longer has
15 ReasonNotInHand = "not_in_hand" // a gun move dropping a gun that is not in a hand box (10.22)
16 ReasonNotBoth = "not_both" // a gun move to a hand of a gun that is not in both hands (10.22)
17 ReasonGunDropped = "gun_dropped" // a gun move dropped the gun the character aims with: its AIM points go
18 ReasonHandFull = "hand_full" // the destination hand already holds a gun
19 ReasonNoRoom = "no_room" // the character already carries MaxGuns weapons
20 ReasonNotCocked = "not_cocked" // shooting an uncocked gun (13.1)
21 ReasonEmpty = "empty" // shooting a gun without shells (13.1)
22 ReasonJammed = "jammed" // shooting or cocking a jammed gun not completely reloaded yet (13.31)
23 ReasonFull = "full" // loading a gun already holding its Ammo limit (10.42)
24 ReasonBroken = "broken" // using or loading an exploded gun (13.31)
25 ReasonNoTarget = "no_target" // the character named is out of the fight (12.6), or is the shooter, or no such seat
26 ReasonOutOfZone = "out_of_zone" // the target is in the blind zone (8.32, 12.41)
27 ReasonNoLOS = "no_los" // no line of sight to the target, an obstacle in the way by the heights (31): an aim is cancelled, a shot is held, AIM points are lost
28 ReasonReveal = "reveal" // revealing an action other than Turn or a gun action (12.44)
29 ReasonTransfer = "transfer" // a new target more than one hex from the markers (12.5)
30 ReasonOwnHex = "own_hex" // a new target moving the markers into or out of the character's own hex (12.5)
31 ReasonNoHex = "no_hex" // aiming at a hex that is not on the board
32 ReasonShot = "shot" // aim spent by a shot (12.43)
33 ReasonStagger = "stagger" // thrown by a STAGGER penalty
34 ReasonMisfire = "misfire" // the shot was cancelled by a MALFUNCTION
35 ReasonEmptyHex = "empty_hex" // a shot at a hex nobody stood in: held (EvNothing)
36 ReasonOutOfFight = "out_of_fight" // a shot at a character killed, passed out, surrendered or run away: held (EvNothing)
37 ReasonOutOfRange = "out_of_range" // a throw farther than the weapon's wielding factor (17.2)
38 ReasonThrow = "throw" // aim spent by a throw (16.13); a thrown weapon landing (17.4)
39 ReasonGunMove = "gun_move" // a gun move dropping the gun in the hex (10.22)
40)Delay and cancel reasons.
Malfunction results.
Steps of a segment, in the order they resolve: the shots (7.52), each seat's action in seat order, then the end of the segment (the occupied-hex penalty, combat results, aims out of the zone). Events of one step happened together; a replay shows the steps one after the other. Turn-start and end-of-turn events have no step (0).
1const (
2 // MaxActionPoints is the time points a plan may spend in a turn (rule 7.3).
3 MaxActionPoints = 5
4 // Segments is the number of segments in a turn (rule 4.1).
5 Segments = 5
6 // EndOfTurn is the Seg of events recorded after segment 5 (cancelled
7 // actions, passing out, the end-of-showdown check); turn-start events
8 // (SERIOUS fatigue, aim lost on the first reveal) have Seg 0.
9 EndOfTurn = Segments + 1
10 // MinPlayers and MaxPlayers bound the seats of a game: the showdown's
11 // characters (Setups) fill the seats in order, each a side of its own.
12 MinPlayers = 2
13 MaxPlayers = 4
14) 1const (
2 VPSurvive = "survive" // +2: conscious and unsurrendered at the end (15.62)
3 VPHoldField = "hold_field" // +2: the only side with survivors (15.63)
4 VPSurrender = "surrender" // -2 (15.41)
5 VPCaptured = "captured" // -4: passed out or surrendered when the enemy holds the field (15.63, 15.7)
6 VPKilled = "killed" // -8 (15.2)
7 VPKill = "kill_enemy" // +2: the enemy who killed him (15.2)
8 VPKnockOut = "knock_out_enemy" // +1: the enemy who crossed off most of his endurance boxes (15.3, 15.41)
9 VPRunAway = "run_away" // -2: moved off the map (15.5); no end-of-showdown points (15.6)
10)Victory point awards (rule 15), for showdowns where each character is a side of its own: there are no allies (no "Ally killed"), and no special rule captures or kills anyone.
ActionGunMove names a gun move in its cancel event.
DeckSize is the number of result cards.
DrawJammed is the Result of a Draw & Cock that moves a jammed gun: it is not cocked (13.31).
LoadUnjammed is the Result of a load that completes a jammed gun (13.31).
MaxAim is the most AIM points a character can hold on a target (12.3).
MaxGuns is how many guns a character can carry (hands and holsters).
NoSeat is the seat value for "nobody": AIM markers on a hex, a wound or a death nobody inflicted.
StartEndurance is the endurance boxes a character starts with (14.2).
VPSharedKill is what each enemy gets when several KILLs land in the same segment: 15.2 shares the "Kill enemy" points, kept whole here.
1const (
2 Miss HitLoc = "-"
3 Bullseye HitLoc = "BE" // the shooter picks the location (13.7)
4 LegHit HitLoc = "LEG"
5 GunHit HitLoc = "GUN" // the gun arm
6 ArmHit HitLoc = "ARM" // the other arm
7 SideHit HitLoc = "SIDE" // a flesh wound
8 BodyHit HitLoc = "BODY"
9 CritHit HitLoc = "CRIT"
10 VitalHit HitLoc = "VITAL"
11 HeadHit HitLoc = "HEAD"
12) 1const (
2 Kill PenaltyKind = "kill" // killed, out of the game
3 Stun PenaltyKind = "stun" // draws N wound cards and loses aim
4 Stagger PenaltyKind = "stagger" // thrown to a hex and facing drawn on two direction cards, then drops
5 Serious PenaltyKind = "serious" // N fatigue cards at the start of every turn; may kill at the end
6 DropGunHand PenaltyKind = "gun_hand" // the weapon in the gun hand drops in the hex
7 GunArm PenaltyKind = "gun_arm" // -N aim time with the gun hand
8 DropOtherHand PenaltyKind = "other_hand" // the weapon in the other hand drops in the hex
9 OtherArm PenaltyKind = "other_arm" // -N aim time with the other hand
10 LegWound PenaltyKind = "leg" // N fatigue cards per hex moved while upright
11 Light PenaltyKind = "light" // draws N fatigue cards
12 LoseAimHit PenaltyKind = "lose_aim" // loses the aim (STRIKING TABLE)
13) 1const (
2 // LoseAim: the character loses its aim (no aim is tracked yet).
3 LoseAim Result = -1
4 // WildShot: every cocked gun goes off without hitting anything, is
5 // uncocked and loses a shell; the aim is lost.
6 WildShot Result = -2
7 // Drop: an upright character turns DOWN, draws 3 delay cards and loses
8 // its aim; no effect when already DOWN.
9 Drop Result = -3
10) 1const (
2 // Alive characters plan and act.
3 Alive Status = iota
4 // Out characters (surrendered, or out of time) are skipped by Resolve.
5 Out
6 // Killed characters are out of the game (14.6).
7 Killed
8 // PassedOut characters carried more delay than endurance for two turns (14.2).
9 PassedOut
10 // RanAway characters moved off the map (15.5): out of the showdown,
11 // their hex the edge hex they left from.
12 RanAway
13)Cards is the result deck in card order, index 0 = card 1.
1var CharKeys = []string{
2 "andy", "axe", "banker", "barkeep", "border_rider", "cattle_baron",
3 "chief", "clerk", "driver", "dude", "eagle", "el_jefe", "fast_draw",
4 "fast_eddie", "floozy", "foreman", "gambler", "guard", "gun_artist",
5 "happy", "hawk", "ike", "innocente", "john_henry", "lady", "lightning",
6 "ling_ho", "little_ernie", "lucky", "marshal", "mountain_man", "nco",
7 "old_man", "owner", "prospector", "quiet_man", "reb", "running_boy",
8 "slim", "smith", "sodbuster", "texas", "the_drifter", "the_kid",
9 "u_s_scout", "veteran", "woman", "yankee",
10}CharKeys are the 48 character tokens a player can pick.
1var Setups = []CharSetup{
2 {Char: "marshal", Hexes: []string{"A-D5", "A-D6", "A-D7", "A-E6", "A-E7"}, Facing: hex.SE},
3 {Char: "the_kid", Hexes: []string{"A-H5", "A-H6", "A-H7", "A-G6", "A-G7"}, Facing: hex.NW},
4 {Char: "reb", Hexes: []string{"A-E8", "A-F7", "A-F8", "A-G8"}, Facing: hex.N},
5 {Char: "yankee", Hexes: []string{"A-E5", "A-F5", "A-F4", "A-G5"}, Facing: hex.S},
6}Setups is the showdown played, one character per seat in seat order, each a side of its own, around the middle of the corral: the Marshal on the west side in D5-D7, E6 and E7, the Kid on the east side in H5-H7, G6 and G7, Reb to the south in E8, F7, F8 and G8, Yankee to the north in E5, F5, F4 and G5. They face the middle: a flat-top grid has no west or east, so the Marshal looks south-east and the Kid north-west; Reb looks north, Yankee south. A character with no entry is not in the showdown; a game of n seats uses the first n.
VPPoints is what each award is worth (the VICTORY POINTS schedule, 15.11). Passing out is worth 0 and makes no award.
AliveCount counts the characters still in the fight.
CanSetUp reports whether charKey may set up in hex id: one of its hexes.
DecodeInts unpacks what EncodeInts produced.
EncodeCharacter packs a character, guns included; DecodeCharacter unpacks it.
EncodeChars packs the characters of a state (a turn's starting snapshot), seats in order; DecodeChars unpacks them.
EncodeEvents packs events into one string; DecodeEvents unpacks it.
EncodeGround packs the weapons lying on the board (a turn's ground at its start), ';'-separated records of id, hex and gun ("1|A-G6|1:colt45:0:0:6:0:0"); DecodeGround unpacks them, skipping a malformed record.
EncodeInts packs numbers (the cards drawn in a turn); DecodeInts unpacks them.
EndShowdown is the end-of-game check (14.5): every character with SERIOUS wounds draws a result card and is killed when its DELAY number plus the wound points reaches four; the enemy who gave the most SERIOUS points gets the kill, enemies tied for the most share it (15.21). The state given is left as it is.
EndTurn is the end-of-turn upkeep (rule 5.6): half of the delay points are removed, rounded up, the per-turn flags are cleared, and a character left with more delay than endurance for the second turn in a row passes out (14.2; checked after the halving). The state given is left as it is.
IsCharKey reports whether s names one of the character tokens.
Resolve plays the plans, one per seat, over the five segments of a turn (rules 5.5, 6, 7, 9, 12, 13, 14), deterministic for a given Drawer; the state given is left as it is. Choices were committed up front and are resolved against each character's live state as the stacks play out.
Each segment, every alive character whose next action is due (usedTime + cost + delay <= segment) executes it once, shots first (7.52), in seat order. Delay gained during a segment and the results of hits take effect from the end of the segment ([H6], 14.1). Actions still pending after segment 5 are cancelled.
SeatChar is the character of a seat, "" for a seat the showdown does not have.
Seed hashes the given parts into shuffle seed material.
ShowdownChars lists the characters of the showdown, seats in order.
VPTotals adds the awards up per seat, for n seats.
EndVictoryPoints scores the end of the showdown (15.6): a character still up survives, and holds the field when it is the only one (15.62, 15.63); Out stands for a surrendered character, who loses the "Surrender" points and, like passing out, gives "Knock out enemy" to the enemy who crossed off most of its endurance boxes (15.41); passed out or surrendered, a character is captured when an enemy holds the field (15.63, 15.7).
TurnVictoryPoints scores what a turn did, from the characters before and after it: a character killed loses the "Killed" points and the enemy whose hit killed it gets "Kill enemy" (15.2, Character.Killers), or, when several enemies share the kill, 1 point each (kept whole); one who passed out gets nothing and the enemy who crossed off most of its endurance boxes "Knock out enemy" (15.3, Character.Hurt). A character who is not up cannot be hit, so a knocked-out one is never killed afterwards.
SetupOf returns the set up of a character, nil when it is not in the showdown.
CloneChars copies the characters field by field. A plain copy of the slice is not enough on a node: a character written earlier in the same transaction stays shared with the live state, so a turn's stored start would show its end position.
DecodeCharacter unpacks what EncodeCharacter produced.
DecodeChars unpacks what EncodeChars produced.
NewDeck shuffles the 108 cards with the seed.
DecodeEvents unpacks what EncodeEvents produced.
VPEvents are the awards as end-of-turn events of the turn's log.
DecodeGround unpacks what EncodeGround produced.
HandLocation maps a plan hand code to the location it designates.
StrikingBullseye is where a thrower's bullseye lands, its choice (the summary of actions): the location of the weapon's STRIKING TABLE line that hurts most, the HEAD for line B (LIGHT 6 and LOSE AIM).
Impact is the IMPACT TABLE: the penalties a hit location inflicts for a gun's table line (rule 13.8). Only line B, the Colt 45's, is transcribed (from the VASSAL module's table); other lines come with their guns.
Strengthen adds a STRENGTH's damage to each GUN ARM, OTHER ARM, LEG, SERIOUS, LIGHT and STUN penalty of a hit (20.21); the others are left as they are.
Striking is the STRIKING TABLE (16.23): the penalties a throw (or, later, an attack) inflicts for a weapon's table line and the hit location. Only line B, the one-handed guns' (with the pail, dynamite, bottle and ammo sources), is transcribed; other lines come with their weapons.
ParsePlan parses the plan string. It checks the syntax and that every card side exists; Validate checks the game rules.
Card returns result card n (1 to 108).
NewState is a showdown of n characters before anyone set up: each upright with its starting guns and endurance, standing nowhere yet (Hex "") until SetUp gives it its hex and facing ([H3], setup.gno).
1type Action struct {
2 Card int
3 Side byte // cards.FrontSide or cards.BackSide
4 Code cards.Code
5 Cost int
6 Dir hex.Rel // committed relative direction, "" when the side takes none
7 Gun int // id of the character's gun for a gun choice (Draw & Cock), 0 when none
8 Ground int // id of the gun on the ground to pick up (Draw & Cock, "g<id>"), 0 when none
9 Hand int // destination hand code for a gun choice (HandGun...), -1 when the side takes none
10 Opt string // option of Cock/Aim/Shoot, Shoot and Throw (OptCock...) or Strength (OptDamage, OptWield), "" when the side takes none
11 Hex string // the hex named by an aim, a shot or a throw at a hex
12 Target int // the seat named by an aim, a shot or a throw at a character; -1 otherwise
13 // Wield and Damage are what the STRENGTHs played on top of a Throw add
14 // to the weapon's wielding factor and to the penalties (20.2), set by
15 // Combine.
16 Wield int
17 Damage int
18 // Moves are the gun moves done when the action is revealed (10.22),
19 // written before it in the plan string.
20 Moves []GunMove
21}Action is one card side chosen for the turn, with its committed choice.
AimTime is the aim time printed on a shooting action or a Throw for a one- or two-handed weapon (13.52, 17.3).
IsShot reports whether the action fires the gun.
IsThrow reports whether the action throws the weapon in hand (17.1).
Award is victory points a character earns (Points > 0) or loses.
Band is an inclusive range of aim times or ranges; Hi < 0 is open-ended.
CharSetup is where a character of the showdown sets up: the hexes it may stand in, and the way it faces unless its player turns it.
1type Character struct {
2 Hex string
3 Facing hex.Dir
4 Down bool
5 Delay int // delay points on the sheet (rule 6)
6 Status Status
7 // PlayedFoot and PlayedRun record whether the current turn's plan holds
8 // a foot action / a Run, whether or not it executes ([H12], rules 13.61-62).
9 PlayedFoot bool
10 PlayedRun bool
11 // RanLastTurn is PlayedRun carried over from the previous turn: Sprint
12 // needs a Run on the previous turn as well (rule 9.23, "build up speed").
13 RanLastTurn bool
14 // Dropped records a DROP penalty this turn ("Move" target status, 13.61).
15 Dropped bool
16 // Guns carried (section 10).
17 Guns Guns
18 // Aim is the AIM points on the target (12.2). AimAt is the seat of the
19 // character the markers follow, wherever it goes (12.3), NoSeat when
20 // they sit on the hex AimHex. Both are meaningless while Aim is 0.
21 Aim int
22 AimAt int
23 AimHex string
24 // Endurance is the boxes left on the sheet (14.2); wound and fatigue
25 // cards cross them off.
26 Endurance int
27 // Exhausted counts the consecutive turn ends with more delay than
28 // endurance; two in a row pass the character out (14.2).
29 Exhausted int
30 // Permanent wounds (14.12): fatigue cards per turn, aim time penalties
31 // per hand, fatigue cards per hex moved upright.
32 Serious int
33 GunArm int
34 OtherArm int
35 Leg int
36 // Who did it, for the victory points (15.2, 15.21, 15.3), by seat: the
37 // seats credited with the kill (several when their KILLs landed in the
38 // same segment, or tied for the most SERIOUS points), the SERIOUS and
39 // LEG points each seat's wounds gave (the fatigue those wounds cost
40 // later is put down to it), and the endurance boxes each seat's hits
41 // crossed off.
42 Killers [MaxPlayers]bool
43 SeriousFrom [MaxPlayers]int
44 LegFrom [MaxPlayers]int
45 Hurt [MaxPlayers]int
46}Character is the mutable state of one gunslinger.
Chart is the hit chart of a FIRE card: a hit location per aim-time row and range column.
Lesser is the hit the card's Target Status entries name: the chart's hit location other than a bullseye (every card has exactly one).
Lookup is the preliminary hit location for an aim time and a range; off the chart is a miss (rule 13.5).
ChartRow is one aim-time row of a Chart.
Deck is the result deck shuffled once from a seed and dealt in order (rule 5.7: the deck is reshuffled when exhausted). The same seed always deals the same cards, so a turn can be replayed from its stored seed.
Draw implements Drawer: the next card of the shuffle, reshuffling the whole deck once every card has been dealt.
Drawn returns the numbers of every card dealt so far, in order: the trace of a turn's draws.
Order returns the card numbers in the order the deck deals them.
Drawer hands out result cards to Resolve.
1type Event struct {
2 Seg int
3 Player int
4 Kind string
5 Action cards.Code
6 From string
7 To string
8 Facing hex.Dir
9 Down bool
10 N int
11 Delay int
12 Reason string
13 Card int // the result card drawn (0 when none)
14 Result string // a card's penalty, a malfunction result or a wound's penalty kind
15 Endurance int // endurance boxes crossed off by a wound or fatigue card
16 Target int // the seat shot at, for shots
17 Hit string // the final hit location of a shot (Miss "-")
18 Range int // the range of a shot, in hexes
19 Gun GunType // the gun's model, for gun events
20 GunID int // the gun's id, for gun events
21 Step int // which part of the segment it belongs to (StepShots, StepEnd, StepAction+seat), 0 outside the segments
22 Chart string // a shot's preliminary hit read on the FIRE card's chart, before Target Status ("" when no chart was read)
23 Status string // the Target Status letters (StatusMove...) that changed a shot's hit, "" when none did
24}Event is one thing that happened during resolution, in order. Seg is 0 for turn-start events and EndOfTurn for those after segment 5.
Fixed is a Drawer that always deals the same card; tests use Fixed(37) (DELAY 1) to match the BGA reference engine's stub.
GroundGun is a weapon lying in a hex (10.21). ID identifies it on the ground for the whole game (plans refer to it as "g<ID>"); the gun's own ID was its previous owner's and is reassigned when picked up.
Gun is one weapon carried by a character. ID identifies it for the whole game (plans refer to it), even among several guns of the same model.
CanFireFrom reports whether the gun is in a box it can shoot from (13.1): a one-handed gun in the gun hand or both hands, a two-handed one in both hands.
GunLocation is where a character keeps a gun (the boxes of the sheet).
GunMove is what a character may do with its guns, for free, each time it reveals an action (10.22): move the gun in BOTH HANDS to one hand, or drop a gun from a hand box into its hex. The other hand, like Draw & Cock's, comes with a second gun: Validate refuses it for now. Its plan string entry, "h<gun id>:<to>", comes before the action it goes with: To is HandGun (0) or HandOther (1), or "g" (HandGround) to drop it ("h1:g,1f:ahead": drop the Colt as the Advance is revealed). Whether the gun is there, where the move needs it, is checked when it is done: it may be one picked up earlier in the plan.
GunSpec is the static data of a gun model (rules section 10 and the WEAPON LISTS).
GunType identifies a weapon model.
Guns is a character's weapons; empty slots have Type NoGun.
At returns the slot of the gun held at a location, or -1.
Blocked reports whether a gun other than the one in slot except holds loc, or a hand box overlapping it: BOTH HANDS takes the gun hand and the other hand, and either hand is taken by a gun in BOTH HANDS.
Count is the number of guns carried.
Find returns the slot of the gun with the given id, or -1.
Firing returns the slot of the gun held in a box it can shoot from (rule 11.3), or -1.
Free returns an empty slot, or -1 when the character carries MaxGuns.
NextID is a free id for a gun added to this character.
HitLoc is a hit location on a FIRE card's hit chart (rule 13.5).
Malfunction is the upper block of cards 101-108 (rule 13.3): whether the shot misfires per shell type, and the gun's fate on a second malfunction drawn after a misfire (13.31).
Penalty is one combat result, with its number when the kind takes one.
PenaltyKind names the combat results of the IMPACT TABLE (rules 14.11, 14.12).
Plan is the ordered stack of actions a player committed for the turn.
Its string form, used as the transaction argument, is a comma-separated list of entries "<card><f|b>[:<choice>]", the choice being a relative direction for move and turn cards ("1f:ahead_left"), for Draw & Cock a gun and the hand it goes to ("9f:1:0": the character's gun 1 to the gun hand, "9f:g2:0": the gun lying in its hex with ground id 2; hand codes: 0 gun hand, 1 other hand, 2 both hands), or for Cock/Aim/Shoot and Shoot the option ("5f:aim:A-F6", "7f:shoot:@1"; a bare "7f" does nothing), for Throw the same ("6b:throw:@1", a bare "6b" does nothing), for Strength its use ("7b:damage", "7b:wield"), e.g. "1f:ahead_left,2f:ahead,3f"; gun moves ("h1:g", GunMove) come before the action they go with and do not count as actions. An empty string is a pass.
Combine folds each run of STRENGTHs into the Throw it is played on top of (20.1): treated as part of that action, revealed with it, their time points added to its own, their bonuses in its Wield and Damage, their gun moves done as it is revealed. Validate has checked that each STRENGTH comes just before a Throw; one that does not is dropped.
Cost is the total time points of the plan.
Has reports whether the plan holds the action.
PlayedFoot reports whether the plan holds any foot action ([H12]).
String is the canonical plan string, parseable by ParsePlan.
Validate checks the plan against the selection rules for the character that will play it (port of the BGA actConfirmPlan checks).
Result is one line of a result card: a number of points, or a named penalty (rules 14.1, 14.21). Points are 0 or more; penalties are negative.
ResultCard is one of the 108 result cards (rule 2.4): N is its number on the card. Delay and Wound are the DELAY and WOUND lines and Hex the HEX line (direction cards, 14.3: a relative direction, hex.Same or hex.Long). The upper block is either a FIRE hit chart with its Target Status letters (cards 1-100, see fire.gno) or a MALFUNCTION block (cards 101-108). The TAC line (optional rule 9) is not used by this game.
Sequence is a Drawer dealing the given card numbers in order, then the last one forever; for tests.
State is the whole game state the engine acts on: one character per seat, in seat order.
Status is the participation state of a character.