From 21ce2dd8f1a09f735610258ca315e0f774f86619 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:24:08 +0000 Subject: [PATCH 1/8] Codex: add the guide for per-character journals Document TF-Minecraft/Codex: its build, journals per character, how account discoveries move to each account's heir, staff commands and the RPCharacters placeholders, which now count characters. Co-Authored-By: Claude Opus 5.5 --- PLATFORM.md | 1 + README.md | 1 + projects/Codex/README.md | 33 +++++++++++++++++++ projects/Codex/overview.md | 25 ++++++++++++++ .../RPCharacters/docs/character-controls.md | 2 +- 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 projects/Codex/README.md create mode 100644 projects/Codex/overview.md diff --git a/PLATFORM.md b/PLATFORM.md index c35896b..67230ce 100644 --- a/PLATFORM.md +++ b/PLATFORM.md @@ -76,6 +76,7 @@ consumer set. Source builds must pass clean verification before publication. | [BarterShops](projects/BarterShops/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [BirdMessenger](projects/BirdMessenger/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [BreedingBuddies](projects/BreedingBuddies/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | +| [Codex](projects/Codex/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [CompanionPets](projects/CompanionPets/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [Cooking](projects/Cooking/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [CoreProtect](projects/CoreProtect/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | diff --git a/README.md b/README.md index f0643c8..66f80d6 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Choose a project to open its technical documentation and source repository link. | [ActivityTF](projects/ActivityTF/README.md) | Daily activity tasks, weekly progress, and player rewards. | | [BirdMessenger](projects/BirdMessenger/README.md) | Bird-delivered letters and interactive mailboxes. | | [BreedingBuddies](projects/BreedingBuddies/README.md) | Farm animal ownership, daily care, inherited genetics, and mount breeding. | +| [Codex](projects/Codex/README.md) | Lore discoveries that each character keeps in its own journal. | | [CompanionPets](projects/CompanionPets/README.md) | Companion pet hatching, care, training, and play. | | [Games](projects/Games/README.md) | Tabletop games, card games, and wagering. | | [GeigerCounters](projects/GeigerCounters/README.md) | Geiger counter treasure hunts with proximity signals and tiered loot. | diff --git a/projects/Codex/README.md b/projects/Codex/README.md new file mode 100644 index 0000000..bd5aef7 --- /dev/null +++ b/projects/Codex/README.md @@ -0,0 +1,33 @@ +# Codex + +[Source repository](https://github.com/TF-Minecraft/Codex) · [All projects](../../README.md) + +TFMC's copy of [Ajneb97/Codex](https://github.com/Ajneb97/Codex): a journal of lore discoveries that each roleplay character keeps for itself. + +TFMC runs Minecraft **1.21.10**. See the [shared platform and build baseline](../../PLATFORM.md) for runtime, build and validation conventions. + +## Build and dependencies + +Run Maven with **JDK 21** from the source checkout. The POM sets `maven.compiler.release=21` and resolves `io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT` with `provided` scope. The plugin descriptor declares `api-version: 1.21.10`. PlaceholderAPI, WorldGuard, WorldEdit, MythicMobs, EliteMobs and Residence come from their public Maven repositories, so Codex has no private build inputs. + +Install `me.plugins:tlibs:2.6.1` with the [shared installer](../TLibs/README.md), then build: + +```bash +python3 path/to/TLibs/tools/install-plugins.py --pom pom.xml --mode pinned && mvn clean verify +``` + +JaCoCo requires 100% line coverage of `net.tfminecraft.codex.character`, the TFMC character code. Upstream code has no tests. + +## Runtime and configuration + +The manifest requires TLibs and loads after RPCharacters, which provides character sessions. WorldGuard, PlaceholderAPI, MythicMobs and Residence are optional. Categories, discoveries, rewards and menus are configured as in upstream Codex; see the [upstream wiki](https://ajneb97.gitbook.io/codex). + +This copy has no MySQL storage, update checker or bStats reporting. Old `mysql_database` and `update_notify` keys in `config.yml` are ignored. + +## Guides + +- [Behaviour and operations](overview.md) + +## Builds and releases + +See the [shared pipeline guide](../../PIPELINES.md) for development artifacts, release tags, and dependency access. diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md new file mode 100644 index 0000000..db79091 --- /dev/null +++ b/projects/Codex/overview.md @@ -0,0 +1,25 @@ +# Codex + +[Project index](README.md) + +## Journals per character + +Each character has its own journal in `plugins/Codex/characters/.yml`. Codex opens it when the character's session starts and saves it when the session ends, whether by switching, quitting, death or shutdown. It also saves open journals every `player_data_save` seconds. A new character starts with an empty journal, so it discovers places and lore again and earns their rewards again, such as the Player EXP for a point of interest. + +Between characters, for example in the selection room, a player has no journal. Discoveries, rewards and `/codex` entries wait until a character is in play. + +A journal file records `owner` (the account UUID), `name` (the account name when last saved) and, for each category, whether it is completed and its discoveries as `id;date;millis`. + +## Discoveries from before characters + +Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. Each of these goes to the character RPCharacters chose as the account's heir at the bodies cutover, the same character that received its money and body. Accounts missing from that review give theirs to their most-played living character, or else their most-played character. Their other characters start empty. + +Codex moves every account file once RPCharacters reports its heirs, a few seconds after start-up, and again at the start of each session. If the heir already has a journal, the two merge: the heir keeps its own entries and gains the rest, and a category counts as completed if either side completed it. The moved file goes to `plugins/Codex/players-migrated/`. An account with no character keeps its file in `players/` until it has one. The server log records each move as `Moved Codex discoveries of account to character `. + +## Staff commands + +`/codex reset [category] [discovery]` resets the journal of the character the player is playing now, and the player must be online. `/codex reset * …` resets every character's journal file and every open journal. + +## Placeholders + +RPCharacters' `codex_percent_` and `codex_holders_` placeholders count character journals; see [character controls](../RPCharacters/docs/character-controls.md#codex-rarity). diff --git a/projects/RPCharacters/docs/character-controls.md b/projects/RPCharacters/docs/character-controls.md index 5ef1c5b..3817faf 100644 --- a/projects/RPCharacters/docs/character-controls.md +++ b/projects/RPCharacters/docs/character-controls.md @@ -52,7 +52,7 @@ The same player must wait 24 hours by default before striking a character again ## Codex rarity -`%rpcharacters_codex_percent_:%` is the nearest whole percent of Codex accounts that have unlocked that entry. `%rpcharacters_codex_holders_:%` is the count. An unknown category or entry is blank. The figure refreshes about once a minute from Codex's saved files, using live Codex data for players who are online. +`%rpcharacters_codex_percent_:%` is the nearest whole percent of Codex journals that have unlocked that entry. `%rpcharacters_codex_holders_:%` is the count. [TFMC Codex](../../Codex/overview.md) keeps a journal per character, so these count characters; with upstream Codex they count accounts. An unknown category or entry is blank. The figure refreshes about once a minute from Codex's saved files, using live Codex data for characters being played. ## Armour takes time From 20e776f2f3b35af63b1dcabd22b9eef82554d73e Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:29:25 +0000 Subject: [PATCH 2/8] Codex: describe out-of-character reference Co-Authored-By: Claude Opus 5.5 --- projects/Codex/overview.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index db79091..498dc2e 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -8,6 +8,12 @@ Each character has its own journal in `plugins/Codex/characters/.yml` Between characters, for example in the selection room, a player has no journal. Discoveries, rewards and `/codex` entries wait until a character is in play. +## Out-of-character reference + +An entry any of the account's characters has found, alive or dead, stays unlocked in `/codex`, and its click actions (sub-pages) still work. 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 only dead characters found it, the line reads "No living 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. + +Codex reads the other characters' journals when a session starts, since they cannot change while the account plays someone else, and again after `/codex reset *`. Category progress, completion rewards and placeholders count only the played character's own discoveries. + A journal file records `owner` (the account UUID), `name` (the account name when last saved) and, for each category, whether it is completed and its discoveries as `id;date;millis`. ## Discoveries from before characters From 416ed306c903d623382178339075817c6b8a8f9c Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:42:18 +0000 Subject: [PATCH 3/8] ConditionalEvents: add the guide for per-character event data Document TF-Minecraft/ConditionalEvents: its build, the data_scope setting, where account and character data are stored, how existing data moves to the heir, and why Main's Codex events need the character scope. Co-Authored-By: Claude Opus 5.5 --- PLATFORM.md | 1 + README.md | 1 + projects/ConditionalEvents/README.md | 34 ++++++++++++++++++++++++++ projects/ConditionalEvents/overview.md | 29 ++++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 projects/ConditionalEvents/README.md create mode 100644 projects/ConditionalEvents/overview.md diff --git a/PLATFORM.md b/PLATFORM.md index 67230ce..de84e73 100644 --- a/PLATFORM.md +++ b/PLATFORM.md @@ -78,6 +78,7 @@ consumer set. Source builds must pass clean verification before publication. | [BreedingBuddies](projects/BreedingBuddies/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [Codex](projects/Codex/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [CompanionPets](projects/CompanionPets/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | +| [ConditionalEvents](projects/ConditionalEvents/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [Cooking](projects/Cooking/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [CoreProtect](projects/CoreProtect/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | | [DenarEconomy](projects/DenarEconomy/README.md) | 21 | `paper-api` | `1.21.10-R0.1-SNAPSHOT` | diff --git a/README.md b/README.md index 66f80d6..259d4eb 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Choose a project to open its technical documentation and source repository link. | [BreedingBuddies](projects/BreedingBuddies/README.md) | Farm animal ownership, daily care, inherited genetics, and mount breeding. | | [Codex](projects/Codex/README.md) | Lore discoveries that each character keeps in its own journal. | | [CompanionPets](projects/CompanionPets/README.md) | Companion pet hatching, care, training, and play. | +| [ConditionalEvents](projects/ConditionalEvents/README.md) | Configured actions for game events, with data per account or per character. | | [Games](projects/Games/README.md) | Tabletop games, card games, and wagering. | | [GeigerCounters](projects/GeigerCounters/README.md) | Geiger counter treasure hunts with proximity signals and tiered loot. | | [Magic](projects/Magic/README.md) | Magic, resonance, artifacts, and shrines. | diff --git a/projects/ConditionalEvents/README.md b/projects/ConditionalEvents/README.md new file mode 100644 index 0000000..ad12085 --- /dev/null +++ b/projects/ConditionalEvents/README.md @@ -0,0 +1,34 @@ +# ConditionalEvents + +[Source repository](https://github.com/TF-Minecraft/ConditionalEvents) · [All projects](../../README.md) + +TFMC's copy of [Ajneb97/ConditionalEvents](https://github.com/Ajneb97/ConditionalEvents): configured actions for Minecraft events, with once-only and cooldown data per account or per character. + +TFMC runs Minecraft **1.21.10**. See the [shared platform and build baseline](../../PLATFORM.md) for runtime, build and validation conventions. + +## Build and dependencies + +Run Maven with **JDK 21** from the source checkout. The POM sets `maven.compiler.release=21` and resolves `io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT` with `provided` scope. The plugin descriptor declares `api-version: 1.21.10`. exp4j is shaded under `net.tfminecraft.conditionalevents.libs.exp4j`. + +ItemsAdder's public API artifact is no longer published, so the build uses the pinned ItemsAdder 4.0.18 jar from ServerAssets. Install `me.plugins:tlibs:2.6.1` with the [shared installer](../TLibs/README.md), prepare the private input, then build: + +```bash +python3 path/to/TLibs/tools/install-plugins.py --pom pom.xml --mode pinned && + (read -rsp 'ServerAssets token: ' GH_TOKEN && echo && export GH_TOKEN && + bash .github/scripts/prepare-release.sh) && + mvn clean verify +``` + +JaCoCo requires 100% line coverage of `net.tfminecraft.conditionalevents.character`, the TFMC character code. Upstream code has no tests. + +## Runtime and configuration + +The manifest requires TLibs and loads after RPCharacters, which provides character sessions. Event types, conditions, actions and variables are configured as in upstream ConditionalEvents; see the [upstream wiki](https://ajneb97.gitbook.io/conditionalevents). This copy has no update checker or bStats reporting, and an old `Config.update_notification` key is ignored. + +## Guides + +- [Behaviour and operations](overview.md) + +## Builds and releases + +See the [shared pipeline guide](../../PIPELINES.md) for development artifacts, release tags, and dependency access. diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md new file mode 100644 index 0000000..983eacf --- /dev/null +++ b/projects/ConditionalEvents/overview.md @@ -0,0 +1,29 @@ +# ConditionalEvents + +[Project index](README.md) + +## Account or character data + +`one_time` and `cooldown` remember who has run an event. By default that memory belongs to the account, as upstream. Set `data_scope: character` to give each roleplay character its own: + +```yaml +Events: + research_bronze: + type: item_interact + one_time: true + data_scope: character +``` + +A per-character event runs only while a character is in play. It does not run at join before a character is chosen, in the selection room, or after the session has ended on quit, so use the account scope for join and leave events. Per-account events behave as before. Any other `data_scope` value logs a warning and counts as `account`. + +Use the character scope for anything a character learns or earns, such as Codex unlocks, since [Codex](../Codex/overview.md) keeps a journal per character. Keep supporter perks and other account rewards per account. The supporter EXP booster is `/tfmc booster` in TFMCCore and is per account. + +## Stored data + +Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. When a character session starts, any account-level data for events now set to the character scope moves to the account's RPCharacters heir, the same character that received the account's money, body and Codex discoveries. An event done once stays done, and the later cooldown start wins. The server log records each move as `Moved per-character event records of account to character `. + +`/ce reset ` and `/ce reset * ` clear the account and every character. + +## Codex events on Main + +`codex.yml` and `codex_research.yml` unlock Codex entries with `one_time` events, so they need `data_scope: character`. Otherwise a second character could not earn an achievement, duchy title or research entry its account already has. From f292549ab8bbc93ead74b5a7da74e1415345a8aa Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:50:29 +0000 Subject: [PATCH 4/8] Codex and ConditionalEvents: review fixes Name /codex resetplayer, explain click actions on entries known only out of character, the closed menu between characters, the bodies requirement and why neither plugin depends on RPCharacters for load order. Co-Authored-By: Claude Opus 5.5 --- projects/Codex/README.md | 2 +- projects/Codex/overview.md | 10 +++++----- projects/ConditionalEvents/README.md | 2 +- projects/ConditionalEvents/overview.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/projects/Codex/README.md b/projects/Codex/README.md index bd5aef7..621ca86 100644 --- a/projects/Codex/README.md +++ b/projects/Codex/README.md @@ -20,7 +20,7 @@ JaCoCo requires 100% line coverage of `net.tfminecraft.codex.character`, the TFM ## Runtime and configuration -The manifest requires TLibs and loads after RPCharacters, which provides character sessions. WorldGuard, PlaceholderAPI, MythicMobs and Residence are optional. Categories, discoveries, rewards and menus are configured as in upstream Codex; see the [upstream wiki](https://ajneb97.gitbook.io/codex). +The manifest requires TLibs. RPCharacters provides character sessions and must run with `character-bodies` enabled; it loads after Codex, because it reads Codex for its placeholders. WorldGuard, PlaceholderAPI, MythicMobs and Residence are optional. Categories, discoveries, rewards and menus are configured as in upstream Codex; see the [upstream wiki](https://ajneb97.gitbook.io/codex). This copy has no MySQL storage, update checker or bStats reporting. Old `mysql_database` and `update_notify` keys in `config.yml` are ignored. diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index 498dc2e..e9379d2 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -6,13 +6,13 @@ Each character has its own journal in `plugins/Codex/characters/.yml`. Codex opens it when the character's session starts and saves it when the session ends, whether by switching, quitting, death or shutdown. It also saves open journals every `player_data_save` seconds. A new character starts with an empty journal, so it discovers places and lore again and earns their rewards again, such as the Player EXP for a point of interest. -Between characters, for example in the selection room, a player has no journal. Discoveries, rewards and `/codex` entries wait until a character is in play. +Between characters, for example in the selection room, a player has no journal. Discoveries and rewards wait until a character is in play, and `/codex` answers `noCharacterInPlay` ("Choose a character to open the Codex.") instead of opening. ## Out-of-character reference -An entry any of the account's characters has found, alive or dead, stays unlocked in `/codex`, and its click actions (sub-pages) still work. 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 only dead characters found it, the line reads "No living 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. +An entry any of the account's characters has found, 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 only dead characters found it, the line reads "No living 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 characters' journals when a session starts, since they cannot change while the account plays someone else, and again after `/codex reset *`. Category progress, completion rewards and placeholders count only the played character's own discoveries. +Codex reads the other characters' journals when a session starts, since they cannot change while the account plays someone else, again after the start-up move of account files, and after `/codex resetplayer *`. Category progress, completion rewards and placeholders count only the played character's own discoveries. A journal file records `owner` (the account UUID), `name` (the account name when last saved) and, for each category, whether it is completed and its discoveries as `id;date;millis`. @@ -20,11 +20,11 @@ A journal file records `owner` (the account UUID), `name` (the account name when Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. Each of these goes to the character RPCharacters chose as the account's heir at the bodies cutover, the same character that received its money and body. Accounts missing from that review give theirs to their most-played living character, or else their most-played character. Their other characters start empty. -Codex moves every account file once RPCharacters reports its heirs, a few seconds after start-up, and again at the start of each session. If the heir already has a journal, the two merge: the heir keeps its own entries and gains the rest, and a category counts as completed if either side completed it. The moved file goes to `plugins/Codex/players-migrated/`. An account with no character keeps its file in `players/` until it has one. The server log records each move as `Moved Codex discoveries of account to character `. +Codex moves every account file once RPCharacters reports its heirs, a few seconds after start-up, and again at the start of each session. RPCharacters reports heirs only when `character-bodies` is enabled; if it has not after 60 seconds, Codex logs a warning and the files wait. A reviewed heir deleted since the review falls through to the most-played rule. If the heir already has a journal, the two merge: the heir keeps its own entries and gains the rest, and a category counts as completed if either side completed it. The moved file goes to `plugins/Codex/players-migrated/`, as `-2.yml` and so on if an earlier copy is already there. An account with no character keeps its file in `players/` until it has one. The server log records each move as `Moved Codex discoveries of account to character `. ## Staff commands -`/codex reset [category] [discovery]` resets the journal of the character the player is playing now, and the player must be online. `/codex reset * …` resets every character's journal file and every open journal. +`/codex resetplayer [category] [discovery]` resets the journal of the character the player is playing now, and the player must be online. `/codex resetplayer * …` resets every character's journal file, every open journal and every account file in `players/` that has not moved yet. ## Placeholders diff --git a/projects/ConditionalEvents/README.md b/projects/ConditionalEvents/README.md index ad12085..06ae78a 100644 --- a/projects/ConditionalEvents/README.md +++ b/projects/ConditionalEvents/README.md @@ -23,7 +23,7 @@ JaCoCo requires 100% line coverage of `net.tfminecraft.conditionalevents.charact ## Runtime and configuration -The manifest requires TLibs and loads after RPCharacters, which provides character sessions. Event types, conditions, actions and variables are configured as in upstream ConditionalEvents; see the [upstream wiki](https://ajneb97.gitbook.io/conditionalevents). This copy has no update checker or bStats reporting, and an old `Config.update_notification` key is ignored. +The manifest requires TLibs. RPCharacters provides character sessions; it is not a load dependency, because SimpleFactions loads after ConditionalEvents and RPCharacters after SimpleFactions. Event types, conditions, actions and variables are configured as in upstream ConditionalEvents; see the [upstream wiki](https://ajneb97.gitbook.io/conditionalevents). This copy has no update checker or bStats reporting, and an old `Config.update_notification` key is ignored. ## Guides diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index 983eacf..66ef663 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -20,7 +20,7 @@ Use the character scope for anything a character learns or earns, such as Codex ## Stored data -Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. When a character session starts, any account-level data for events now set to the character scope moves to the account's RPCharacters heir, the same character that received the account's money, body and Codex discoveries. An event done once stays done, and the later cooldown start wins. The server log records each move as `Moved per-character event records of account to character `. +Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. When a character session starts, any account-level data for events now set to the character scope moves to the account's RPCharacters heir (or, if that heir has since been deleted, its most-played living character), the same character that received the account's money, body and Codex discoveries. An event done once stays done, and the later cooldown start wins. The server log records each move as `Moved per-character event records of account to character `. `/ce reset ` and `/ce reset * ` clear the account and every character. From 512befc9f917abd75dd8adeca6545882ea57d5a5 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:58:30 +0000 Subject: [PATCH 5/8] Codex and ConditionalEvents: no character inherits old data Old account journals and event data stay as out-of-character reference or unused; every character starts fresh. Co-Authored-By: Claude Opus 5.5 --- projects/Codex/README.md | 2 +- projects/Codex/overview.md | 10 ++++------ projects/ConditionalEvents/overview.md | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/projects/Codex/README.md b/projects/Codex/README.md index 621ca86..b1e44fb 100644 --- a/projects/Codex/README.md +++ b/projects/Codex/README.md @@ -20,7 +20,7 @@ JaCoCo requires 100% line coverage of `net.tfminecraft.codex.character`, the TFM ## Runtime and configuration -The manifest requires TLibs. RPCharacters provides character sessions and must run with `character-bodies` enabled; it loads after Codex, because it reads Codex for its placeholders. WorldGuard, PlaceholderAPI, MythicMobs and Residence are optional. Categories, discoveries, rewards and menus are configured as in upstream Codex; see the [upstream wiki](https://ajneb97.gitbook.io/codex). +The manifest requires TLibs. RPCharacters provides character sessions; it loads after Codex, because it reads Codex for its placeholders. WorldGuard, PlaceholderAPI, MythicMobs and Residence are optional. Categories, discoveries, rewards and menus are configured as in upstream Codex; see the [upstream wiki](https://ajneb97.gitbook.io/codex). This copy has no MySQL storage, update checker or bStats reporting. Old `mysql_database` and `update_notify` keys in `config.yml` are ignored. diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index e9379d2..86a6b5e 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -10,21 +10,19 @@ Between characters, for example in the selection room, a player has no journal. ## Out-of-character reference -An entry any of the account's characters has found, 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 only dead characters found it, the line reads "No living 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, 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`. -Codex reads the other characters' journals when a session starts, since they cannot change while the account plays someone else, again after the start-up move of account files, and after `/codex resetplayer *`. Category progress, completion rewards and placeholders count only the played character's own discoveries. +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. A journal file records `owner` (the account UUID), `name` (the account name when last saved) and, for each category, whether it is completed and its discoveries as `id;date;millis`. ## Discoveries from before characters -Upstream Codex kept one journal per account in `plugins/Codex/players/.yml`. Each of these goes to the character RPCharacters chose as the account's heir at the bodies cutover, the same character that received its money and body. Accounts missing from that review give theirs to their most-played living character, or else their most-played character. Their other characters start empty. - -Codex moves every account file once RPCharacters reports its heirs, a few seconds after start-up, and again at the start of each session. RPCharacters reports heirs only when `character-bodies` is enabled; if it has not after 60 seconds, Codex logs a warning and the files wait. A reviewed heir deleted since the review falls through to the most-played rule. If the heir already has a journal, the two merge: the heir keeps its own entries and gains the rest, and a category counts as completed if either side completed it. The moved file goes to `plugins/Codex/players-migrated/`, as `-2.yml` and so on if an earlier copy is already there. An account with no character keeps its file in `players/` until it has one. The server log records each move as `Moved Codex discoveries of account to character `. +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. ## Staff commands -`/codex resetplayer [category] [discovery]` resets the journal of the character the player is playing now, and the player must be online. `/codex resetplayer * …` resets every character's journal file, every open journal and every account file in `players/` that has not moved yet. +`/codex resetplayer [category] [discovery]` resets the journal of the character the player is playing now, and the player must be online. `/codex resetplayer * …` resets every character's journal file, every open journal and every account file in `players/`. ## Placeholders diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index 66ef663..86c7657 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -20,7 +20,7 @@ Use the character scope for anything a character learns or earns, such as Codex ## Stored data -Each account's file, `plugins/ConditionalEvents/players/.yml`, keeps account events under `events` and per-character events under `characters..events`. When a character session starts, any account-level data for events now set to the character scope moves to the account's RPCharacters heir (or, if that heir has since been deleted, its most-played living character), the same character that received the account's money, body and Codex discoveries. An event done once stays done, and the later cooldown start wins. The server log records each move as `Moved per-character event records of account to character `. +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: an event switched to the character scope starts fresh for every character, and its old account-level entries stay in the file, unused. `/ce reset ` and `/ce reset * ` clear the account and every character. From 7c9a5215ed45959502ae81a2e77ddab68c3f57fc Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:06:34 +0000 Subject: [PATCH 6/8] Codex and ConditionalEvents: delayed actions and failed saves Co-Authored-By: Claude Opus 5.5 --- projects/Codex/overview.md | 2 +- projects/ConditionalEvents/overview.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/Codex/overview.md b/projects/Codex/overview.md index 86a6b5e..39089fd 100644 --- a/projects/Codex/overview.md +++ b/projects/Codex/overview.md @@ -4,7 +4,7 @@ ## Journals per character -Each character has its own journal in `plugins/Codex/characters/.yml`. Codex opens it when the character's session starts and saves it when the session ends, whether by switching, quitting, death or shutdown. It also saves open journals every `player_data_save` seconds. A new character starts with an empty journal, so it discovers places and lore again and earns their rewards again, such as the Player EXP for a point of interest. +Each character has its own journal in `plugins/Codex/characters/.yml`. Codex opens it when the character's session starts and saves it when the session ends, whether by switching, quitting, death or shutdown. It also saves open journals every `player_data_save` seconds. If a journal cannot be written when its session ends, Codex logs an error, keeps it in memory and retries with every save; the character gets it back if it returns first. A new character starts with an empty journal, so it discovers places and lore again and earns their rewards again, such as the Player EXP for a point of interest. Between characters, for example in the selection room, a player has no journal. Discoveries and rewards wait until a character is in play, and `/codex` answers `noCharacterInPlay` ("Choose a character to open the Codex.") instead of opening. diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index 86c7657..6af671a 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -14,7 +14,7 @@ Events: data_scope: character ``` -A per-character event runs only while a character is in play. It does not run at join before a character is chosen, in the selection room, or after the session has ended on quit, so use the account scope for join and leave events. Per-account events behave as before. Any other `data_scope` value logs a warning and counts as `account`. +A per-character event runs only while a character is in play, and never for events without a player such as `player_pre_join` or `server_start`. It 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 are dropped and the run's one-time flag and cooldown are undone, so the character can earn it again. It does not run at join before a character is chosen, in the selection room, or after the session has ended on quit, so use the account scope for join and leave events. Per-account events behave as before. Any other `data_scope` value logs a warning and counts as `account`. Use the character scope for anything a character learns or earns, such as Codex unlocks, since [Codex](../Codex/overview.md) keeps a journal per character. Keep supporter perks and other account rewards per account. The supporter EXP booster is `/tfmc booster` in TFMCCore and is per account. From cd8beca8b22bc494363ca9e3050b99fe724112b6 Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:09:03 +0000 Subject: [PATCH 7/8] ConditionalEvents: character is the default data scope Co-Authored-By: Claude Opus 5.5 --- projects/ConditionalEvents/README.md | 2 +- projects/ConditionalEvents/overview.md | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/projects/ConditionalEvents/README.md b/projects/ConditionalEvents/README.md index 06ae78a..ac03d50 100644 --- a/projects/ConditionalEvents/README.md +++ b/projects/ConditionalEvents/README.md @@ -2,7 +2,7 @@ [Source repository](https://github.com/TF-Minecraft/ConditionalEvents) · [All projects](../../README.md) -TFMC's copy of [Ajneb97/ConditionalEvents](https://github.com/Ajneb97/ConditionalEvents): configured actions for Minecraft events, with once-only and cooldown data per account or per character. +TFMC's copy of [Ajneb97/ConditionalEvents](https://github.com/Ajneb97/ConditionalEvents): configured actions for Minecraft events, with once-only and cooldown data per character by default, or per account. TFMC runs Minecraft **1.21.10**. See the [shared platform and build baseline](../../PLATFORM.md) for runtime, build and validation conventions. diff --git a/projects/ConditionalEvents/overview.md b/projects/ConditionalEvents/overview.md index 6af671a..b3ec830 100644 --- a/projects/ConditionalEvents/overview.md +++ b/projects/ConditionalEvents/overview.md @@ -4,26 +4,28 @@ ## Account or character data -`one_time` and `cooldown` remember who has run an event. By default that memory belongs to the account, as upstream. Set `data_scope: character` to give each roleplay character its own: +`one_time` and `cooldown` remember who has run an event. In this copy that memory belongs to the roleplay character being played. Set `data_scope: account` to keep it per account instead, as upstream: ```yaml Events: - research_bronze: - type: item_interact + act1_exp_catchup: + type: repetitive one_time: true - data_scope: character + data_scope: account ``` -A per-character event runs only while a character is in play, and never for events without a player such as `player_pre_join` or `server_start`. It 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 are dropped and the run's one-time flag and cooldown are undone, so the character can earn it again. It does not run at join before a character is chosen, in the selection room, or after the session has ended on quit, so use the account scope for join and leave events. Per-account events behave as before. Any other `data_scope` value logs a warning and counts as `account`. +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. -Use the character scope for anything a character learns or earns, such as Codex unlocks, since [Codex](../Codex/overview.md) keeps a journal per character. Keep supporter perks and other account rewards per account. The supporter EXP booster is `/tfmc booster` in TFMCCore and is per account. +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 are dropped and the run's one-time flag and cooldown are undone, so the character can earn it again. 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. ## 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: an event switched to the character scope starts fresh for every character, and its 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`. 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. `/ce reset ` and `/ce reset * ` clear the account and every character. -## Codex events on Main +## Events on Main -`codex.yml` and `codex_research.yml` unlock Codex entries with `one_time` events, so they need `data_scope: character`. Otherwise a second character could not earn an achievement, duchy title or research entry its account already has. +Main has 90 events that keep data. The 87 Codex unlocks in `codex.yml` and `codex_research.yml` and the meditation cooldown in `r_lore.yml` are per character by default, so a second character can earn an achievement, duchy title or research entry its account already has. `act1_exp_catchup` and `act1_exp_catchup_retry` set `data_scope: account`, so the one-off catch-up from before characters had their own progress does not arm again for every character. From e5214936f0d550371d58c8df83d281162267c5ac Mon Sep 17 00:00:00 2001 From: Ryan Barlow <7389646+ryanbarlow97@users.noreply.github.com> Date: Wed, 14 Oct 2026 22:11:21 +0000 Subject: [PATCH 8/8] ConditionalEvents: nested groups and undo limits 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 b3ec830..ce12abb 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 are dropped and the run's one-time flag and cooldown are undone, so the character can earn it again. 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. 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`. 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.