Table of Contents

Class WaypointUnlockMask

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

The waypoints a character has discovered in one scene, as a growable bit set: bit N of page N / 64 is set when waypoint N is unlocked.

public sealed class WaypointUnlockMask
Inheritance
WaypointUnlockMask
Inherited Members

Remarks

Why a bit set. A scene has tens of waypoints, every character eventually unlocks most of them, and the whole set is read and written together: on login, in the spawn payload, and on save. One row per (character, waypoint) would be a forty-byte row for a single bit; the set stores those bits as bits. The same shape is on the wire and in the database (character_waypoints, one row per non-empty page), so nothing translates between representations — see CharacterDialogueChoiceData for the precedent.

Why pages. A single 64-bit word would cap a scene at 64 waypoints, and the day that cap is hit is the day a designer's sixty-fifth waypoint silently fails to persist. Pages make the set unbounded (to MaxIndex, a sanity cap on authoring rather than on storage) at the cost of one extra small integer per row.

Persistence without a version. Bits are only ever set, and the database merge is an OR. So "what still needs writing" is exactly unlocked & ~persisted, and confirming a write is persisted |= written; a bit set while a write was in flight is not in written and stays dirty. No counter to bump and no stale-confirmation hazard — the trap the versioned tables fell into (see the attribute/ability persistence notes).

Fields

BitsPerPage

Bits per page. A page is one ulong and one database row.

public const int BitsPerPage = 64

Field Value

int

MaxIndex

Highest waypoint index a scene may author. Sixteen pages. A bound on authoring mistakes and on what a payload may ask the controller to allocate, not a design limit anyone is expected to reach.

public const int MaxIndex = 1023

Field Value

int

MaxPages

Most pages a scene can have, derived from MaxIndex.

public const int MaxPages = 16

Field Value

int

Properties

IsDirty

Whether any page is dirty.

public bool IsDirty { get; }

Property Value

bool

IsEmpty

Whether no waypoint is unlocked.

public bool IsEmpty { get; }

Property Value

bool

PageCount

Number of pages allocated. Trailing pages may be empty.

public int PageCount { get; }

Property Value

int

Methods

Add(int)

Unlocks a waypoint.

public bool Add(int waypointIndex)

Parameters

waypointIndex int

Returns

bool

True when the bit was newly set; false when it was already set or the index is invalid.

BitOf(int)

The bit an index occupies within its page.

public static ulong BitOf(int waypointIndex)

Parameters

waypointIndex int

Returns

ulong

Clear()

Drops everything.

public void Clear()

CollectDirtyPages(string, List<WaypointPageSnapshot>)

Appends every page with unconfirmed bits.

public void CollectDirtyPages(string sceneName, List<WaypointPageSnapshot> results)

Parameters

sceneName string

The scene, stamped onto each snapshot.

results List<WaypointPageSnapshot>

Receives the dirty pages.

Contains(int)

Whether a waypoint is unlocked.

public bool Contains(int waypointIndex)

Parameters

waypointIndex int

Returns

bool

GetPage(int)

The unlocked bits of a page. Zero for a page beyond the allocated range.

public ulong GetPage(int page)

Parameters

page int

Returns

ulong

IsPageDirty(int)

Whether any bit of a page has not been confirmed by the database.

public bool IsPageDirty(int page)

Parameters

page int

Returns

bool

IsValidIndex(int)

Whether an index is within [0, MaxIndex].

public static bool IsValidIndex(int waypointIndex)

Parameters

waypointIndex int

Returns

bool

MarkPersisted(int, ulong)

Records that the database holds these bits of a page.

public void MarkPersisted(int page, ulong writtenMask)

Parameters

page int
writtenMask ulong

PageOf(int)

Which page an index lives on.

public static int PageOf(int waypointIndex)

Parameters

waypointIndex int

Returns

int

Restore(int, ulong)

Installs persisted bits: unlocked and already confirmed, so they are not dirty.

public void Restore(int page, ulong mask)

Parameters

page int
mask ulong

Remarks

OR-ed in, never assigned. A restore arriving after an unlock in the same session (a slow load racing a quick interaction) must not drop the unlock; and on the owner client the payload may be re-read on a pooled respawn.