This folder holds The Broken Seal's game rules and the tables they read: the party's units and their stats, a new game and the prologue, items and inventories, Psynergy and levelling up, the game flags, enemy units, the party's coins and counters, element levels and classes, battle arithmetic and the Djinn.
See also: Battles, which follows an ability from these tables to its damage, and Shops, which sell the items.
| File | What it holds |
|---|---|
| game.c | the guide to the game object: it includes game_internal.h, then the parts in game/ in ROM order |
| game_internal.h | the object's includes, and Inventory_CompactSlots, which two parts use |
| game/battle_calc.c | damage and success rates: the attack, Psynergy and healing formulas, the element multiplier, the effect rolls and the weapon unleash |
| starting_equipment.c | the characters given starting equipment |
| *.tsv with the .s beside them | the definition tables (below) |
| Table | One row per | Placed as | Label column |
|---|---|---|---|
| items.tsv | item, by item id (324) | gItem_DefinitionTable (item_table.s) | item |
| actions.tsv | ability, by ability id (519) | gBattleAction_DefinitionTable (actions.s) | ability |
| djinn.tsv | Djinni, 20 to an element: Venus, Mercury, Mars, Jupiter (80) | gDjinn_DefinitionTable (djinn_table.s) | djinni |
| enemies.tsv | enemy, by enemy id (165) | gEnemy_Definitions (enemies.s) | enemy |
| summons.tsv | summon (16) | summons.s | none |
| classes.tsv | class (203) | classes.s | none |
| chars.tsv, elempre.tsv, artifact_slots.tsv, level_experience_*.tsv | character, element preset, artifact slot, level | their .s | none |
Each .tsv has a name:type header, one row per entry, and no row numbers: the first row after the header is entry 0. The build writes it to a .table beside it, which its .s places with its label. Edit the .tsv. A column named without a type, such as item, is a label for people: the build skips it and writes nothing for it. A column named unknown_ or unk_ is a field whose meaning is not known yet; reserved_ and pad_ name bytes that are zero in every row.
The guide's comment says where to start, and each part's second line says what it holds: head -2 game/*.c lists them. A part includes the private header, so it resolves when opened on its own, but it is compiled only through game.c. The ROM shows the game rules as one object; the parts are ours, cut where one family ends and the next begins. Link order is in games/tbs/objects.tsv, from game.
The unit headers are in games/tbs/include/unit/game/. Code in other banks reaches these functions through the far-call table games/tbs/src/system/far_call/GAME.S (the ...Far names), so a rename crosses folders.
| Prefix | What it acts on |
|---|---|
| Unit_, UnitGet, UnitCalc, UnitRatio, Owner_ | one unit: stats, HP and PP, Psynergy, levels, elements |
| Party_, GameState_, Game_ | the party and the game state |
| Item_, Inventory_, PartyInventory_, InventorySnapshot_, ItemCounter_, Equipment_ | items: one unit's inventory, the party's, and the snapshot the Colosso takes |
| Character_, Class_, Enemy_, Summon_, SummonDefinition_, BattleAction_ | one entry of a definition table |
| GameFlag_ | the game flags |
| Djinn_, DjinnRecovery_ | the Djinn, and their standby lists |
| Battle_, BattleRandom, BattleTarget_, BattleFx_ | battle arithmetic the battle folder calls |
| BattleUnitSet | filling an enemy unit at the start of a battle |
The spellings some sites keep to match, and the comment markers, are in Matching.
The definition tables have no id column. An item is the row it sits on, and the same number is its place in three other lists: its name is message MsgItemName + id, its line on the item screen MsgItemPlainName + id, and code reaches both by adding the id to the first message's number (itemId + MsgItemName in the shops and the menus). Abilities, enemies and Djinn work the same way, with their own first messages. So the tables and the message catalogs are parallel lists tied only by position: a row inserted in the middle of items.tsv gives every later item the name of the one before it, unless the catalogs of all six languages gain a message at the same place. Rows that no item uses keep their places for the same reason, with ? or = as their names.
The 4,096 game flags are one array of bits, gGameFlagBytes. A flag number's low three bits pick the bit and the next nine the byte (game/flags.c), so eight consecutive flags are also one byte, and the byte calls (GameFlag_GetByte, GameFlag_SetByte, GameFlag_IncrementByte) read and write it whole. A small counter can therefore live among the flags, and it follows the flags' rules: one kept in a scene's temporary range (0x200 to 0x2ff) is cleared on entry with the rest (see Scenes), and all of them are saved with the game.
A unit's 15 inventory slots are halfwords: the item id in the low 9 bits, then the equipped bit (INVENTORY_EQUIPPED, 0x200), the broken bit (INVENTORY_BROKEN, 0x400), and the quantity less one from bit 11 (INVENTORY_QUANTITY_SHIFT). So an item, its state and its stack move together in one load and one store, and a slot of 0 is empty, which Inventory_CompactSlots relies on when it closes the gaps. Code that asks which item a slot holds masks it with ITEM_ID_MASK first, since the same item equipped, broken or stacked is a different halfword.
Search the table for the English name in its label column: Healing Ring in items.tsv, Quake in actions.tsv, Flint in djinn.tsv, Vermin in enemies.tsv. The row's id is its line number less two (the header is line 1, entry 0 is line 2). The labels are the English edition's names from games/tbs/text/en.po: an item's name is message MsgItemName + id (386 + id), an enemy's MsgEnemyName + id (655 + id), an ability's MsgAbilityName + id (819 + id), and a Djinni's MsgDjinnName + its row (1119 + row), which is also its ability, 300 + row. A row whose message is ? or = is unused, and the labels keep those marks; a row past the last name message says (no name message). item_ids.h, ability_ids.h and djinn_ids.h name the ids the code uses.
An item is its row of items.tsv (struct ItemDefinition in games/tbs/include/game/item.h):
An item names an ability by its row in actions.tsv, in two columns:
The ability's row of actions.tsv then gives its element, power, range and kind; ../battle/README.md follows it to the damage.
The tables' label columns are the English edition's names from games/tbs/text/en.po, by the message each row's id reaches; the columns are named from what the code reads in them; the item effect kinds from what UnitCalc does with each. item_ids.h, ability_ids.h and djinn_ids.h name only the ids code uses.
Still unknown:
Source: src/game