From 54b1d608070cc78a41bdd21ddc1be0794074d416 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:23:11 +0000 Subject: [PATCH 1/4] Codex and ConditionalEvents: one-off copy to the most-played character Co-Authored-By: Claude Opus 5.5 --- projects/Codex/overview.md | 6 ++++-- projects/ConditionalEvents/overview.md | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index 39089fd..10421e7 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -10,7 +10,7 @@ Between characters, for example in the selection room, a player has no journal. ## Out-of-character reference -An entry the account found before journals were per character, or that any of its characters has found since (alive or dead), stays unlocked in `/codex`. Its click actions, such as the lore sub-pages on Main, still run, unless the entry sets `click_actions_cooldown`: that cooldown is kept on the character's own entry, so an entry with one runs its click actions only for a character that found it itself. Its hover text then names the living characters who can use it in character, the played character first: "Aldric and Mira can use this in character." If no living character found it itself, for example an entry from before journals were per character, the line reads "No character can use this in character." When the played character has not found the entry itself, a further line says "Aldric knows this only out of character." These three lines are `knownInCharacterBy`, `knownInCharacterByNobody` and `knownOutOfCharacterOnly` in `messages.yml`, and Codex adds them to existing files along with `noCharacterInPlay`. +An entry the account found before journals were per character, or that any of its characters has found since (alive or dead), stays unlocked in `/codex`. Its click actions, such as the lore sub-pages on Main, still run, unless the entry sets `click_actions_cooldown`: that cooldown is kept on the character's own entry, so an entry with one runs its click actions only for a character that found it itself. Its hover text then names the living characters who can use it in character, the played character first: "Aldric and Mira can use this in character." If no living character found it itself, the line reads "No character can use this in character." When the played character has not found the entry itself, a further line says "Aldric knows this only out of character." These three lines are `knownInCharacterBy`, `knownInCharacterByNobody` and `knownOutOfCharacterOnly` in `messages.yml`, and Codex adds them to existing files along with `noCharacterInPlay`. Codex reads the other journals when a session starts, since they cannot change while the account plays someone else, and again after `/codex resetplayer *`. Category progress, completion rewards and placeholders count only the played character's own discoveries. @@ -18,7 +18,9 @@ A journal file records `owner` (the account UUID), `name` (the account name when ## Discoveries from before characters -Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. Those journals do not record which character found an entry, so no character inherits them: every character, the most-played one included, starts with an empty journal and earns each discovery and its rewards again. The account files stay where they are and feed the out-of-character reference above. +Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. As a one-off, at the start of an account's first character session after the change, Codex copies that journal into the journal of the account's most-played living character (else its most-played character), using RPCharacters' playtime at that moment. That character knows those entries in character; every other character starts with an empty journal and earns each discovery and its rewards again. If the most-played character already had a journal, the two merge: it keeps its own entries, and a category counts as completed if either side completed it. + +The account file stays where it is and feeds the out-of-character reference above. It gains `seeded-to: ` so the copy never repeats. A failed copy is logged as `Could not copy the old Codex of account …` and retried at the account's next session; a successful one as `Copied old Codex discoveries of account to its most-played character `. ConditionalEvents gives the account's old per-character event data to the same character. ## Staff commands diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index ce12abb..e7b7bfd 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -22,7 +22,7 @@ Keep anything a character learns or earns per character, such as Codex unlocks, ## Stored data -Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. Old per-account data does not record which character ran an event, so no character inherits it: events that are per character start fresh for every character, and their old account-level entries stay in the file, unused. +Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. As a one-off, on an account's first character session after the change, its old account-level entries for events that are now per character move to its most-played living character (else its most-played character), the same character [Codex](../Codex/overview.md) copies the old journal to. An event done once stays done, and the later cooldown start wins. The file records `seeded-to: ` so this happens once; if RPCharacters cannot list the account's characters yet, it waits for a later session. Every other character starts these events fresh. Account-scoped events keep their data on the account. `/ce reset ` and `/ce reset * ` clear the account and every character. From 2b092f7a8936962640ce1a92ff93135d7413b374 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:30:09 +0000 Subject: [PATCH 2/4] Codex and ConditionalEvents: pinned recipient and save retries Co-Authored-By: Claude Opus 5.5 --- projects/Codex/overview.md | 2 +- projects/ConditionalEvents/overview.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index 10421e7..c6cb1d4 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -18,7 +18,7 @@ A journal file records `owner` (the account UUID), `name` (the account name when ## Discoveries from before characters -Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. As a one-off, at the start of an account's first character session after the change, Codex copies that journal into the journal of the account's most-played living character (else its most-played character), using RPCharacters' playtime at that moment. That character knows those entries in character; every other character starts with an empty journal and earns each discovery and its rewards again. If the most-played character already had a journal, the two merge: it keeps its own entries, and a category counts as completed if either side completed it. +Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. As a one-off, at the start of an account's first character session after the change, Codex copies that journal into the journal of the account's most-played living character (else its most-played character), using RPCharacters' playtime at that moment. The choice is pinned in `plugins/TLibs/legacy-recipients/.txt`, which ConditionalEvents reads too, so both give the account's old data to the same character and a retry never picks another. That character knows those entries in character; every other character starts with an empty journal and earns each discovery and its rewards again. If the most-played character already had a journal, the two merge: it keeps its own entries, and a category counts as completed if either side completed it. The account file stays where it is and feeds the out-of-character reference above. It gains `seeded-to: ` so the copy never repeats. A failed copy is logged as `Could not copy the old Codex of account …` and retried at the account's next session; a successful one as `Copied old Codex discoveries of account to its most-played character `. ConditionalEvents gives the account's old per-character event data to the same character. diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index e7b7bfd..c7f5b52 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -22,7 +22,9 @@ Keep anything a character learns or earns per character, such as Codex unlocks, ## Stored data -Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. As a one-off, on an account's first character session after the change, its old account-level entries for events that are now per character move to its most-played living character (else its most-played character), the same character [Codex](../Codex/overview.md) copies the old journal to. An event done once stays done, and the later cooldown start wins. The file records `seeded-to: ` so this happens once; if RPCharacters cannot list the account's characters yet, it waits for a later session. Every other character starts these events fresh. Account-scoped events keep their data on the account. +Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. As a one-off, on an account's first character session after the change, its old account-level entries for events that are now per character move to its most-played living character (else its most-played character), the same character [Codex](../Codex/overview.md) copies the old journal to, pinned in `plugins/TLibs/legacy-recipients/.txt`. An event done once stays done, and the later cooldown start wins. The file records `seeded-to: ` so this happens once; if RPCharacters cannot list the account's characters yet, it waits for a later session. Every other character starts these events fresh. Account-scoped events keep their data on the account. + +Player files are written through a temporary file. A failed save is logged and the data stays in memory, even after a quit, until a later save succeeds. `/ce reset ` and `/ce reset * ` clear the account and every character. From 618b4499f16533c0273ae3d549185528fb435dea Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:34:58 +0000 Subject: [PATCH 3/4] ConditionalEvents: data kept until restart; reset of offline files Co-Authored-By: Claude Opus 5.5 --- projects/ConditionalEvents/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index c7f5b52..952145e 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -24,9 +24,9 @@ Keep anything a character learns or earns per character, such as Codex unlocks, Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. As a one-off, on an account's first character session after the change, its old account-level entries for events that are now per character move to its most-played living character (else its most-played character), the same character [Codex](../Codex/overview.md) copies the old journal to, pinned in `plugins/TLibs/legacy-recipients/.txt`. An event done once stays done, and the later cooldown start wins. The file records `seeded-to: ` so this happens once; if RPCharacters cannot list the account's characters yet, it waits for a later session. Every other character starts these events fresh. Account-scoped events keep their data on the account. -Player files are written through a temporary file. A failed save is logged and the data stays in memory, even after a quit, until a later save succeeds. +Player data stays in memory from an account's first login until the server restarts; this copy has no `retain_player_data_until_restart` setting, and an old key is ignored. Player files are written through a temporary file, and a failed save is logged and retried by the next save. -`/ce reset ` and `/ce reset * ` clear the account and every character. +`/ce reset ` and `/ce reset * ` clear the account and every character. `/ce reset *` resets accounts in memory there, and rewrites only the files of accounts not loaded since the last restart. ## Events on Main From cb80a0849a8d37854e6ea813dcc9e484bf06f9da Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:37:55 +0000 Subject: [PATCH 4/4] ConditionalEvents: drop the obsolete retention note Co-Authored-By: Claude Opus 5.5 --- projects/ConditionalEvents/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index 952145e..b266ce5 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -16,7 +16,7 @@ Events: The scope only matters for events with `one_time` or a `cooldown` that involve a player. Other events have nothing to keep and run as upstream: join messages, `server_start`, `player_pre_join`, and commands without a cooldown. -An event that keeps per-character data runs only while a character is in play, so not at join before a character is chosen, in the selection room, or after the session has ended on quit. Use `data_scope: account` for join and leave events that keep data. A run belongs to the character it started for: if that character leaves before a delayed action is due, for example during `wait_ticks`, the rest of the actions, including action groups it calls with `execute_action_group`, are dropped, and the run's one-time flag and cooldown are undone so the character can earn it again. The undo skips anything a later run or a staff reset changed since. With `retain_player_data_until_restart: false`, a player who logs out mid-run has already been saved, so the marks stay; Main keeps player data until restart. Any `data_scope` value other than `character` or `account` logs a warning and counts as `character`. +An event that keeps per-character data runs only while a character is in play, so not at join before a character is chosen, in the selection room, or after the session has ended on quit. Use `data_scope: account` for join and leave events that keep data. A run belongs to the character it started for: if that character leaves before a delayed action is due, for example during `wait_ticks`, the rest of the actions, including action groups it calls with `execute_action_group`, are dropped, and the run's one-time flag and cooldown are undone so the character can earn it again. The undo skips anything a later run or a staff reset changed since. Any `data_scope` value other than `character` or `account` logs a warning and counts as `character`. Keep anything a character learns or earns per character, such as Codex unlocks, since [Codex](../Codex/overview.md) keeps a journal per character. Use `data_scope: account` for supporter perks and other account rewards. The supporter EXP booster is `/tfmc booster` in TFMCCore and is per account.