Data Patterns
Recurring structural patterns found across Darkstar's IL2CPP game tables. Understanding these conventions is essential for correctly extracting and interpreting raw field data.
Core Data Patterns
4 patternsQuotient / Exponent Scaling
NumericLarge values in Darkstar are not stored as single fields. Instead, they use a float quotient + int exponent pair to represent numbers that can span hundreds of orders of magnitude.
value = quotient × 10exponent
How it works
- The quotient is a float, typically between 1.0 and 9.999...
- The exponent is an integer power of 10
- Together they form a scientific-notation value covering 300+ orders of magnitude
Example
| Field | Value | Result |
|---|---|---|
fPowerQuotient |
1.5 | 1,500 |
iPowerExponent |
3 |
1.5 × 103 = 1,500
NumberUnit system.
String CSV + Parsed Arrays
Dual-fieldMany table fields come in pairs: a raw CSV string and a corresponding parsed array. Both are populated at load time, and during extraction we capture both for cross-validation.
sFieldName (string CSV) → eFieldName (parsed int/enum array)
Example
"1,3,17"
eEquipEffectTypes
[1, 3, 17]
Why extract both?
- The string version is the raw source-of-truth from the encrypted data tables
- The parsed array is what the game runtime actually uses
- Comparing both catches parsing bugs and confirms extraction accuracy
- If the parsed array differs from the CSV, the game's parser may apply transformations we need to replicate
s prefix (e.g. sEquipEffectTypes).
Parsed arrays use e prefix for enum arrays or i/f
for int/float arrays (e.g. eEquipEffectTypes, fEquipEffectValues).
Localization IDs
Display
Display strings (names, descriptions, tooltips) are not stored inline.
Instead, each table record holds an integer ID that resolves to a localized string
via the GetString(id) lookup.
iName (int ID) → GetString(iName) → resolved display string
Example
12345
iName_resolved
"Aegis Cruiser"
Extraction strategy
- We extract the raw integer ID for stable cross-referencing between tables
- We also extract the resolved name via
GetString()for human readability - Resolved fields use the
_resolvedsuffix in our JSON output - The same ID always resolves to the same string within a game version, but the mapping can change between patches
Reference / Awakening
Identity
Entity tables use a two-part identity system: iReferenceID
identifies the base entity, and iAwakening identifies the
tier or evolution level. The same logical entity at different awakenings appears as
separate records in the table.
iReferenceID (base entity) + iAwakening (tier 0, 1, 2...) = unique record
How it works
iReferenceIDgroups all awakening tiers of the same ship, admiral, or itemiAwakeningis typically 0 (base), 1, 2, etc. for each tier upgrade- Each awakening tier can have different stats, skills, and visual assets
- The combination of
(iReferenceID, iAwakening)forms the composite primary key
Example: Ship awakening chain
| iReferenceID | iAwakening | Name | Notes |
|---|---|---|---|
1001 |
0 |
Aegis Cruiser | Base form |
1001 |
1 |
Aegis Cruiser +1 | First awakening |
1001 |
2 |
Aegis Cruiser +2 | Second awakening |
iReferenceID only. The awakening tier is either inherited from context or
resolved separately. See Cross-Table Relationships for
full join paths.
Pattern Summary
| Pattern | Fields | Used In | Purpose |
|---|---|---|---|
| Quotient / Exponent | fXxxQuotient + iXxxExponent |
Ships, Skills, Stages, Bosses | Large number encoding (300+ OOM) |
| String CSV + Array | sXxx + eXxx / iXxx |
Memory Cards, Equipment, Skills | Multi-value fields with cross-validation |
| Localization IDs | iName, iDescription |
All entity tables | Locale-independent string references |
| Reference / Awakening | iReferenceID + iAwakening |
Ships, Admirals, Equipment | Composite primary key for tiered entities |