Repository navigation
Game tables
Most of WildStar's rules live in the client's game tables: every item, quest, creature, spell and archive article is a row. This page covers how the server loads and reads them, and the switch that decides which ones it loads at all. The byte layouts are on Game tables file formats.
The 16042 client ships 384 game tables (.tbl) and a text table per language (.bin), packed in its archives. Running it locally extracts them with NexusForever.MapGenerator. They're the client's own data, so they never go in the repository; every server reads them from your extract.
| Term | Meaning |
|---|---|
| Table | One .tbl file: a fixed-width row per id, with a string table at the end |
| Row model | The C# class a table's rows are read into, named after the table plus Entry: ArchiveArticle.tbl becomes ArchiveArticleEntry
|
[GameData] |
The attribute on a GameTableManager property that makes the server load that table |
| Text table |
en-US.bin and its siblings: localized strings by id |
LocalizedTextId |
A row field holding the id of a string in the text tables, not the string itself |
GameTableManager declares a property for 377 tables, and only the ones carrying [GameData] load: 132 of them on stable, plus all three text tables.
A property without the attribute isn't an error. It just stays null, and the first code that touches it throws, long after start-up. A table that nothing reads is the clearest sign a system was never started, so switching one on is the first step of most features (Adding a player feature).
A row model's fields are matched to the file's columns in declaration order, not by name: the first field is the first column, and the first field is always the id. An array field marked [GameTableFieldArray(n)] takes n columns in a row.
A Debug build checks every loaded model against its file at start-up, by column count and by type, and stops on a mismatch. A Release build doesn't check, and reads a wrong model into wrong values without a word.
Note
Every row model with a 16042 table was checked against it, by column count and type order, and all of them match, including the tables nothing loads. That check can't see two same-typed fields in the wrong order, so compare a field's name with the column's before trusting what it means.
The world server loads every switched-on table in parallel at start-up. Any table that fails to load is reported by name, and start-up stops after the batch.
The text tables are the exception. A missing en-US.bin isn't caught at load: it surfaces later as a null reference in the customisation code. A missing French or German table only logs a warning.
The chat and friendship servers load just one table each, the word filter, through a smaller loader.
| Need | Do | Cost |
|---|---|---|
| One row by id |
GameTableManager.Instance.<Table>.GetEntry(id), which returns null for an unknown id |
A single array lookup |
| Rows by anything else | Scan Entries, the rows in file order |
Linear, so build a dictionary once at start-up if it's hot |
| A row's text | GetTextTable(language).GetEntry(localizedTextId) |
A single array lookup |
| A row by its name |
SearchManager, which keeps a reverse index of every string |
Used by commands like teleport name and item lookup
|
A feature that needs a lookup the tables don't offer builds it once at start-up, the way the Galactic Archive builds its unlock rule index.
| Knob | Where | Effect |
|---|---|---|
GameTable:GameTablePath |
WorldServer.json, ChatServer.json, FriendshipServer.json
|
The folder holding the .tbl and .bin files. Relative paths resolve against the server's own folder |
[GameData] |
Each property in GameTableManager.cs
|
Whether that table loads |
| The build configuration | Debug or Release | Whether row models are checked against their files |
GameTable:Cache |
The example configs | Nothing at the moment: the cache it configures isn't called |
| Piece | Path |
|---|---|
| The table properties and the loader | Source/NexusForever.GameTable/GameTableManager.cs |
| Reading a table and the layout check | Source/NexusForever.GameTable/GameTable.cs |
| Text tables | Source/NexusForever.GameTable/TextTable.cs |
| Row models | Source/NexusForever.GameTable/Model/ |
| Reverse text search | Source/NexusForever.GameTable/Text/Search/ |
| The subset loader for chat and friendship | Source/NexusForever.GameTable/GameTableLoader.cs |
Guides
- Running it locally
- Using the web console
- Adding a player feature
- Verifying a feature
- Taking a change upstream
- Syncing with upstream
Explanation
- Server architecture
- Login handshake
- Game tables
- Branches and workflow
- Upstream branches
- Contributing
- Galactic Archive
- Account entitlements
Reference
- Processes and projects
- File formats
- Databases
- Web console
- Galactic Archive messages and storage
- Code style
- Code patterns
- Pull requests
Design
About this wiki