documentor

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package documentor extracts reference data from a flattened Total Annihilation install and renders the markdown catalogues consumed by the standalone github.com/coreprime/reference-ta repo.

Index

Constants

View Source
const SlotsPerPage = 6

SlotsPerPage is TA's per-page build-menu grid (2 columns × 3 rows). TA: Kingdoms does not use this grid concept — its canbuild/*.tdf files carry a linear Priority instead.

Variables

This section is empty.

Functions

func Generate

func Generate(opts Options) error

Generate is the package-level entrypoint that drives one full extract → render → portrait-batch cycle.

func SideOf

func SideOf(unitname string) string

SideOf returns "ARM", "CORE", or "OTHER" based on a unit's name prefix. (TA convention — uses 3-char prefix.)

func SideOfTAK

func SideOfTAK(unitname string) string

SideOfTAK maps a 3-char unit-name prefix to its TA: Kingdoms side short code. Accepts both internal codes (ARA, TAR, …) and unit-name prefixes; falls back to the literal prefix uppercased.

func TAKSideLabel

func TAKSideLabel(side string) string

TAKSideLabel returns the player-friendly side name for a TA:K code.

Types

type BuildData

type BuildData struct {
	// CanBuild maps a builder's UnitName → the raw ordered list of
	// canbuild units from sidedata.tdf (unannotated).
	CanBuild map[string][]string

	// MenuEntries is the flat list of every [MENUENTRY] across every
	// download/*.tdf, preserving the source filename for tracing.
	MenuEntries []MenuEntry

	// Slots is the merged builder → slot list (page/button derived).
	Slots map[string][]BuildSlot
}

BuildData groups every parsed (builder → slots) relationship.

type BuildPage

type BuildPage struct {
	Page  int               // 1-indexed page number
	Slots map[int]BuildSlot // button (0..5) → slot
}

BuildPage is one menu page of a builder's buildables.

type BuildSideView

type BuildSideView struct {
	Side       string
	Label      string
	SideAnchor string
	Total      int
	Tiers      []BuildTierGroup
}

BuildSideView is one side of the build-tree page.

type BuildSlot

type BuildSlot struct {
	Page   int // 1-indexed
	Button int // 0..5
	Unit   string
	Source string
}

BuildSlot is the resolved page/button position for one unit registered against one builder. Source is "sidedata" or a download filename.

func (BuildSlot) IsDownload

func (s BuildSlot) IsDownload() bool

IsDownload reports whether this slot came from a download/*.tdf.

type BuildTierGroup

type BuildTierGroup struct {
	Key      CategoryKey
	Heading  string // e.g. "Arm — Commander"
	Anchor   string // GitHub slug for the heading
	Builders []BuilderView
}

BuildTierGroup buckets builders by tier within a side.

type BuildTreeView

type BuildTreeView struct {
	TotalBuilders int
	TotalPairs    int
	DownloadPairs int
	Sides         []BuildSideView
	Reverse       []ReverseSideView
	Unbuildable   []string // unit names that no builder reaches

	// UnitByKey lets slot-rendering helpers in the template resolve a
	// slot's UnitName to its display data without threading the map
	// through every nested call.
	UnitByKey map[string]Unit
}

BuildTreeView is the top-level view-model for ta-buildtree.md.

func BuildBuildTreeView

func BuildBuildTreeView(ds *Dataset) BuildTreeView

BuildBuildTreeView prepares the view-model for the build-tree page.

type BuilderView

type BuilderView struct {
	Builder       string
	Unit          Unit
	Pages         []BuildPage // sorted by Page
	Total         int
	DownloadCount int
}

BuilderView is one builder's worth of build pages.

type CategoryGroup

type CategoryGroup struct {
	Key     CategoryKey
	Heading string // full heading text, e.g. "ARM — Commander"
	Anchor  string // GitHub-style slug for the heading
	Units   []Unit
}

CategoryGroup is one heading-level section: all units (or builders) that share a category, in display order.

type CategoryKey

type CategoryKey struct {
	Sort  string // e.g. "00", "10", … (controls render order)
	Label string // section heading
}

CategoryKey is a sortable group key. The numeric prefix orders sections deterministically; the second element is the human-readable label.

func BuilderTier

func BuilderTier(b string, units map[string]Unit) CategoryKey

BuilderTier categorises a builder for the build-tree page layout.

func BuilderTierTAK

func BuilderTierTAK(b string, units map[string]Unit) CategoryKey

BuilderTierTAK is the build-tree tier for a TA:K builder. TA:K's build hierarchy is broadly: monarch → castle/keep → unit trainers (academies, churches, stables, etc.).

func UnitCategory

func UnitCategory(u Unit) CategoryKey

UnitCategory groups a unit into one of the high-level role buckets used by the ta-units.md table.

func UnitCategoryTAK

func UnitCategoryTAK(u Unit) CategoryKey

UnitCategoryTAK groups a TA: Kingdoms unit into a role bucket. Heavily heuristic — TA:K's `tedclass` carries a side name rather than a role, so we lean on the category tokens and unit-name suffixes.

type Dataset

type Dataset struct {
	Game      Game
	Units     []Unit
	UnitByKey map[string]Unit // keyed by uppercased UnitName

	Weapons     []Weapon
	WeaponByKey map[string]Weapon // keyed by uppercased NameKey

	Build BuildData
}

Dataset is everything one regeneration run needs to render.

func Extract

func Extract(flatRoot string, game Game) (*Dataset, error)

Extract walks a flattened install of the given game and returns the populated dataset. flatRoot is expected to be the root of a flattened install (the same shape kbot mount --flatten produces).

type Game

type Game string

Game identifies which title's reference catalogue we're rendering. Values are the canonical games-registry ids ("totala", "takingdoms"); the documentor layers its own filename prefixes and per-game rendering rules on top, but identity and display names come from the registry.

const (
	// GameTotalA is Total Annihilation (1997) + Core Contingency + Battle Tactics.
	GameTotalA Game = "totala"

	// GameTAKingdoms is Total Annihilation: Kingdoms (1999) + Iron Plague.
	GameTAKingdoms Game = "takingdoms"
)

func ParseGame

func ParseGame(s string) (Game, error)

ParseGame coerces a CLI string into a Game value: shorthand aliases map to canonical ids and anything else must be a registered game id, so a game added to the registry is documentable without touching this file.

func (Game) HumanName

func (g Game) HumanName() string

HumanName returns the player-friendly title from the games registry.

func (Game) PortraitDir

func (g Game) PortraitDir() string

PortraitDir is the per-game portrait subdirectory (relative to target).

func (Game) PortraitExt

func (g Game) PortraitExt() string

PortraitExt is the on-disk file extension portraits land at after a game's batch run. TA writes PNGs (converted from PCX); TA:K writes JPGs (copied verbatim from anims/buildpic/*.jpg).

func (Game) Prefix

func (g Game) Prefix() string

Prefix is the per-game filename/identifier prefix:

  • totala → "ta"
  • takingdoms → "tak"
type MenuEntry struct {
	Builder string // UNITMENU=
	Menu    int    // MENU= (1-indexed page)
	Button  int    // BUTTON= (0..5)
	Unit    string // UNITNAME=
	Source  string // basename of the file the entry came from
}

MenuEntry is one [MENUENTRY] section from a download/*.tdf.

type Options

type Options struct {
	// Game selects which title to document. Default: GameTotalA.
	Game Game

	// Source is the path to the flattened install (the same shape
	// "kbot mount --flatten" produces).
	Source string

	// Target is the root of the reference repo to write into.
	// <prefix>-*.md files land at Target/; portraits at
	// Target/img/<prefix>-units/. Prefix is "ta" or "tak" per game.
	Target string

	// SkipPortraits disables the unitpics/*.pcx → PNG batch step.
	SkipPortraits bool

	// PortraitsSkipExisting avoids re-converting portraits that already
	// exist at the destination. Default true; pass false to force a
	// fresh batch.
	PortraitsSkipExisting bool

	// Logger writes one-line progress messages.  Pass nil to silence.
	Logger func(format string, args ...any)
}

Options controls a single documentation run.

type PortraitResult

type PortraitResult struct {
	Converted int
	Skipped   int // already present and Skip mode enabled
	Failed    int
}

PortraitResult summarises a portrait batch conversion run.

func ConvertPortraits

func ConvertPortraits(flatRoot, outDir string, skipExisting bool) (PortraitResult, error)

ConvertPortraits is a thin wrapper that dispatches to the right per-game pipeline. Use the game-typed entry point in new code.

func ConvertPortraitsForGame

func ConvertPortraitsForGame(flatRoot, outDir string, skipExisting bool, game Game) (PortraitResult, error)

ConvertPortraitsForGame routes to the per-game portrait pipeline:

  • GameTotalA → unitpics/*.pcx, decoded and re-encoded as PNG
  • GameTAKingdoms → anims/buildpic/*.jpg, copied verbatim

outDir is created if missing. If skipExisting is true, files already present at the destination are left alone (cheap reruns). Failures are logged to stderr and counted but do not abort the batch.

type ReverseEntry

type ReverseEntry struct {
	Unit     Unit   // the buildable target
	Builders []Unit // resolved builder Unit records
}

ReverseEntry is one buildable-unit row in the reverse index.

type ReverseSideView

type ReverseSideView struct {
	Side    string
	Label   string
	Total   int
	Entries []ReverseEntry
}

ReverseSideView groups reverse entries by side.

type SideView

type SideView struct {
	Side       string // "ARM" / "CORE" / "OTHER"
	Label      string // "Arm" / "Core" / "Other"
	SideAnchor string // GitHub-style anchor for the side heading
	Total      int
	Groups     []CategoryGroup // already sorted by Key.Sort
}

SideView is the view-model passed to the units template, one block per side.

type Unit

type Unit struct {
	File        string
	UnitName    string
	Side        string
	Name        string
	Description string
	Designation string
	Objectname  string
	Category    string
	TEDClass    string

	// TA dual-resource cost (empty on TA:K).
	BuildMetal  string
	BuildEnergy string
	// TA:K single-resource cost (empty on TA).
	BuildCost string

	BuildTime string
	MaxDamage string

	// TA-style weapon name refs (empty on TA:K which inlines weapons).
	Weapon1 string
	Weapon2 string
	Weapon3 string

	// TA:K inline weapons (empty on TA).
	InlineWeapons []Weapon

	IsFeature string
	Commander string
}

Unit is a parsed entry from a units/*.fbi file. Fields are populated best-effort — missing keys come back as empty strings or zero values.

The struct mixes TA and TA:K fields; per-game extractors leave the inapplicable ones empty (e.g. TA has BuildMetal+BuildEnergy and no BuildCost; TA:K has BuildCost and no metal/energy split).

func (Unit) HasWeapon

func (u Unit) HasWeapon() bool

HasWeapon reports whether the unit declares at least one weapon.

func (Unit) Weapons

func (u Unit) Weapons() []string

Weapons returns the non-empty weapon refs for the unit, in order. For TA the result is the FBI's Weapon1/2/3 ref strings; for TA:K it's the inline [WEAPONn] section names (which are unique per FBI).

type UnitsView

type UnitsView struct {
	TotalUnits int
	Sides      []SideView
}

UnitsView is the top-level view-model for ta-units.md.

func BuildUnitsView

func BuildUnitsView(ds *Dataset) UnitsView

BuildUnitsView prepares the side-/category-grouped view-model for the units page.

type Weapon

type Weapon struct {
	File          string // source filename
	NameKey       string // [SECTION_NAME] — the key units refer to (TA) or "[WEAPONn]" (TA:K)
	Display       string // "name=" field
	ID            string
	Range         string
	Reload        string
	Velocity      string
	AOE           string
	DefaultDamage string
	Archetypes    []string // ballistic, lineofsight, … (TA); or just "type=" (TA:K)
	RenderType    string

	// Owner is the UnitName whose FBI carries this weapon as an inline
	// sub-section. Empty for TA weapons (which live in their own TDFs).
	Owner string
}

Weapon is a parsed entry from a weapons/*.tdf section (TA) or from a unit FBI's inline [WEAPONn] sub-section (TA:K).

func (Weapon) ArchetypeString

func (w Weapon) ArchetypeString() string

ArchetypeString returns archetypes joined with ", " or "—".

type WeaponGroup

type WeaponGroup struct {
	Key     CategoryKey
	Weapons []Weapon
}

WeaponGroup is one heading-level group of weapons.

type WeaponUserMap

type WeaponUserMap map[string][]string

WeaponUserMap is a reverse cross-reference: weapon key (upper) → unit names that use it.

type WeaponsView

type WeaponsView struct {
	TotalWeapons    int
	UnitsWithWeapon int
	Groups          []WeaponGroup
	UserMap         WeaponUserMap   // key → sorted list of unit names
	UserKeys        []string        // sorted keys of UserMap
	Defined         map[string]bool // weapon key → defined-here flag
}

WeaponsView is the top-level view-model for ta-weapons.md.

func BuildWeaponsView

func BuildWeaponsView(ds *Dataset) WeaponsView

BuildWeaponsView prepares the view-model for the weapons page.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL