Documentation
¶
Overview ¶
Package games is the seam between kbot's shared TA-format machinery and the behaviour that genuinely differs per game. The formats packages stay data-driven — a TNT or COB announces its own dialect through version words, and parsing dispatches on what the bytes say. Everything that instead depends on which GAME an install is — palette resolution rules, sound-event wiring, terrain groups, branding — lives behind the Game/Adapter interfaces here, with one implementation per game under games/totala and games/takingdoms.
A custom game built on the TA formats extends this cleanly: implement Game (usually by embedding one of the shipped games and overriding the parts that differ), Register it, and point a kbot context's `game` id at it.
Unit-meta building: the asset bridge that turns a unit's FBI (plus its weapon TDF data) into the simulation's fixed-point stat block. Both shipped games funnel through the same pipeline — the TA pass resolves Weapon1/2/3 references through the caller's weapons index, and the TA:K pass fills any slots the FBI declares inline — so detection is data-driven: a file's own shape decides which passes contribute, and a custom game's units work with either convention.
Index ¶
- func ApplyTAKWeapons(m *sim.UnitMeta, u *tak.Unit)
- func CanbuildDirOptions(fs VFS) map[string][]string
- func DownloadMenuOptions(fs VFS) map[string][]string
- func GlobalPalette(fs VFS, embedded []byte) *gaf.Palette
- func IDs() []string
- func MergeBuildOptions(base, extras []string) []string
- func MetaFromUnitInfo(name string, info *ta.UnitInfo, ...) *sim.UnitMeta
- func Register(g Game)
- func SidedataBuildOptions(fs VFS) map[string][]string
- func UnitMetaFromFBI(name string, fbi []byte, resolve WeaponResolver) (*sim.UnitMeta, error)
- type Adapter
- type Game
- type PaletteResolver
- type Tileset
- type VFS
- type WeaponResolver
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyTAKWeapons ¶
ApplyTAKWeapons fills any empty weapon slots from a TA:Kingdoms unit's inline [WEAPONn] sections. TA:K FBIs carry the weapon definitions as top-level siblings of [UNITINFO] instead of weapons/*.tdf references, so the ref-based loop in MetaFromUnitInfo finds nothing for them. Both asset bridges (native flattened-tree and studio VFS) call this after the TA pass so a unit gets identical stats on the authority and in the browser.
func CanbuildDirOptions ¶
CanbuildDirOptions reads TA:K's canbuild/<builder>/<unit>.tdf grants: builder (upper-case) → buildable names ordered by [Menu] Priority then name.
func DownloadMenuOptions ¶
DownloadMenuOptions reads download/*.tdf [MENUENTRY*] sections — the add-on mechanism both games' mods use — returning builder (upper-case) → added names ordered by (MENU, BUTTON, file order).
func GlobalPalette ¶
GlobalPalette loads the install's global palette (palettes/palette.pal) with the embedded TA palette as fallback, never returning nil. Shared by both games: TA uses it for everything, TA:K as the last-resort fallback when a side palette is missing.
func IDs ¶
func IDs() []string
IDs lists the registered game ids in sorted order, for help text and error messages.
func MergeBuildOptions ¶
MergeBuildOptions appends extras onto base, deduplicating while keeping first-seen order.
func MetaFromUnitInfo ¶
func MetaFromUnitInfo(name string, info *ta.UnitInfo, resolveWeapon func(ref string) (ta.Weapon, bool)) *sim.UnitMeta
MetaFromUnitInfo converts a parsed FBI [UNITINFO] block into the simulation's fixed-point stat block. resolveWeapon maps an FBI weapon reference (Weapon1/2/3) to its parsed TDF section, returning ok=false for an unknown ref. Both asset bridges — the native flattened-tree provider and the studio VFS provider — funnel through here so a unit gets identical stats regardless of where the bytes were read from.
func Register ¶
func Register(g Game)
Register adds a game to the registry. The shipped games register themselves from their package init; a custom game does the same from its own package.
func SidedataBuildOptions ¶
SidedataBuildOptions reads TA's [CANBUILD] table: builder (upper-case) → ordered buildable names (lower-case).
func UnitMetaFromFBI ¶
UnitMetaFromFBI parses raw FBI bytes and builds the full stat block: the TA reference pass first, then the TA:K inline-weapon pass for any slots still empty.
Types ¶
type Adapter ¶
type Adapter interface {
Game() Game
PaletteResolver
// CursorPalette returns the palette for the cursors GAF, or nil when the
// game uses the global palette (the caller then falls back to it).
CursorPalette() *gaf.Palette
// UnitSounds resolves a unit's sound-event map for its FBI sound
// category: TA-style event keys (select1, ok1, arrived1, …) to .wav
// stems. Returns nil when the category resolves to nothing.
UnitSounds(category string) map[string]string
// Tilesets lists the map editor's terrain groups: TA's fixed world list,
// TA:K's kingdoms from sidedata.
Tilesets() []Tileset
// MapTerrainGroup names the terrain group a map belongs to when the
// game tracks it outside the map file itself — TA:K reads the kingdom=
// affinity from the sibling .ota. "" when the game has no such notion
// (TA's planet lives in the .ota planet= the caller already parses).
MapTerrainGroup(mapPath string) string
// BuildOptions lists the unit names (lower-case, ordered as the game's
// menus order them) a builder unit can construct, resolved from the
// game's canbuild data plus any download-menu add-ons. Empty for
// non-builders.
BuildOptions(unit string) []string
}
Adapter is a Game bound to a mounted install: every per-game decision the shared studio/server code needs, answered against that install's data.
type Game ¶
type Game interface {
// ID is the kbot context identifier ("totala", "takingdoms").
ID() string
// Name is the human-readable title.
Name() string
// NewAdapter binds the game's rules to one mounted install. Adapters
// cache parsed game data (sidedata, sound tables) for their lifetime,
// so sessions should hold one adapter, not re-create them per request.
NewAdapter(fs VFS) Adapter
}
Game identifies one supported game and builds per-session adapters for it. Implementations are stateless singletons; all per-install caching lives on the Adapter.
type PaletteResolver ¶
type PaletteResolver interface {
// TexturePalette returns the palette for a 3DO model texture GAF (by VFS path).
TexturePalette(gafPath string) *gaf.Palette
// ModelColorPalette returns the palette for a 3DO model's colour-keyed
// primitives (by object/model name).
ModelColorPalette(object string) color.Palette
// FeaturePalette returns the palette for a feature / anim sprite GAF.
FeaturePalette(gafName string) *gaf.Palette
// TerrainPalette returns the palette for a map's terrain + baked minimap
// (by map VFS path).
TerrainPalette(mapPath string) color.Palette
// TextureRenderOptions returns how 3DO model textures resolve
// transparency, given the resolved palette. TA renders unit textures
// fully opaque (palette[TI] is a real colour); TA:Kingdoms texture
// atlases reserve a transparent key colour which must be punched out.
TextureRenderOptions(pal *gaf.Palette) gaf.RenderOptions
// TextureSidePrefix returns the side name-prefix (lowercase, e.g. "ara")
// for a 3DO model name, or "" when sides don't apply.
TextureSidePrefix(object string) string
// TexturePaletteForSide returns the texture palette for an explicit side
// prefix (the ?side= a client passes with a texture fetch), or nil when
// the side is unknown / sides don't apply.
TexturePaletteForSide(side string) *gaf.Palette
}
PaletteResolver decides which palette applies to each kind of game asset. Rendering code consults the resolver and never special-cases the game.
Total Annihilation keys everything off one global palette. TA:Kingdoms has no global palette — gamedata/sidedata.tdf assigns each side a `nameprefix`, a texture `palette` and a `buildpalette`, and terrain uses a per-kingdom table; its resolver maps an asset's name prefix to its palette.
type Tileset ¶
type Tileset struct {
Slug string `json:"slug"`
Label string `json:"label"`
DefaultTileset string `json:"defaultTileset"`
}
Tileset is one terrain set selectable when creating a new map. JSON tags match the studio's /api/studio/tilesets response shape so adapters' results serialize directly.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package takingdoms implements games.Game for Total Annihilation: Kingdoms.
|
Package takingdoms implements games.Game for Total Annihilation: Kingdoms. |
|
Package totala implements games.Game for Total Annihilation: one global palette for every asset class, sound events from gamedata/sound.tdf, and the classic fixed world list for the map editor.
|
Package totala implements games.Game for Total Annihilation: one global palette for every asset class, sound events from gamedata/sound.tdf, and the classic fixed world list for the map editor. |