Galactic Archive messages and storage - rebaserHEAD/NexusForever GitHub Wiki

reference, committed verified 2026-10-14 stable 36921cd6

The Galactic Archive's unlock rule types, network messages, flag words and saved table. Why it works the way it does is on Galactic Archive.

Game tables

Unlock rule types

The ArchiveEntryUnlockRuleEnum field of an ArchiveEntryUnlockRule row, read as ArchiveEntryUnlockRuleType:

Value Name Fires
0 Achievement When the achievement is completed
1 PathMission Never on game_rework: nothing completes a path mission
2 Quest When the quest is handed in
Table fact Value
Rules in the table 867
Rules in the index 847
Rules skipped, entry in no article 20, counted in the start-up line
Objects per rule Up to 6, Object00 to Object05; 0 is empty
Rule flag 0x01, all objects required Set on no row. A row with it is skipped with a warning

Table flags

Row field Bit Name Effect on the server
ArchiveEntry.ArchiveEntryFlags 0x01 ScientistOnly None
ArchiveEntry.ArchiveEntryFlags 0x02 HiddenWhileLocked None; the client leaves the entry out while it's locked
ArchiveEntry.ArchiveEntryFlags 0x04 UnlockWithArticle The entry opens the first time its article does
ArchiveArticle.ArchiveArticleFlags 0x01 NoClientUnlock The client's unlock message is refused. Set on no row

On the wire

Messages

Opcode Message Direction Handled
0x0102 ServerGalacticArchiveRefresh Server to client Not sent
0x0103 ClientGalacticArchiveUnlock Client to server Yes
0x0104 ServerGalacticArchiveUpdate Server to client Yes
0x0105 ClientGalacticArchiveViewed Client to server Yes
Message Fields, in order
ClientGalacticArchiveUnlock Article id, 14 bits
ClientGalacticArchiveViewed Article id, 14 bits
ServerGalacticArchiveUpdate Article id, 14 bits; unlocked word, 32 bits; viewed word, 32 bits

[!IMPORTANT] The article id is 14 bits in all three. Before #587 the models read and wrote it as 32 bits, which put both flag words in the update 18 bits out of place.

ServerGalacticArchiveUpdate is absolute: the client replaces both of its words with the ones sent.

Unlocked word

Bits Name Meaning
0 to 15 Entries Bit N is the entry in slot N of the article's row, ArchiveEntryId00 to ArchiveEntryId15, by position, not by entry id
16 to 29 Unused, written as zero
30 Viewed The article has been opened
31 Unlocked The article is unlocked. Without it, the client doesn't list the article

The names are the members of ArchiveArticleUnlockFlags.

Viewed word

What the player has read. On a view, both sides apply:

viewed   = viewed | unlocked | 0x40000000
unlocked = unlocked | 0x40000000

Example

Achievement 1385 opens the entries in slots 0 and 1 of article 11:

After Unlocked word Viewed word
achievement grant 1385 0x80000003 0x00000000
Opening the article in the panel 0xC0000003 0xC0000003

Saved table

character_archive_article in the character database, created by the GalacticArchive migration:

Column Type Holds
id bigint(20) unsigned The character id. Key, and a foreign key to character with cascade delete
articleId smallint(5) unsigned The article id. Key
unlockedFlags int(10) unsigned The unlocked word, exactly as sent
viewedFlags int(10) unsigned The viewed word, exactly as sent

A row is inserted when the character first unlocks the article. After that, a save writes only the words that changed.

Where the code lives

Piece Path
Rule index Source/NexusForever.Game/GalacticArchive/GlobalGalacticArchiveManager.cs
Per-character state Source/NexusForever.Game/Entity/GalacticArchiveManager.cs
One article and its save Source/NexusForever.Game/Entity/ArchiveArticle.cs
Interfaces Source/NexusForever.Game.Abstract/Entity/IGalacticArchiveManager.cs, Source/NexusForever.Game.Abstract/Entity/IArchiveArticle.cs, Source/NexusForever.Game.Abstract/GalacticArchive/IGlobalGalacticArchiveManager.cs
Flags and rule types Source/NexusForever.Game.Static/GalacticArchive/
Message handlers Source/NexusForever.WorldServer/Network/Message/Handler/GalacticArchive/
Message models Source/NexusForever.Network.World/Message/Model/GalacticArchive/
Saved model Source/NexusForever.Database.Character/Model/CharacterArchiveArticleModel.cs
Migration Source/NexusForever.Database.Character/Migrations/20261014021019_GalacticArchive.cs
Table loading [GameData] on ArchiveArticle, ArchiveEntry and ArchiveEntryUnlockRule in Source/NexusForever.GameTable/GameTableManager.cs