Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions projects/CompanionPets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ for runtime, build, and validation conventions.
- [Pet types and ModelEngine](docs/models.md) — bodies, eggs, animation clips, and
model authoring
- [Staff commands](docs/staff.md) — commands, permissions, and audit
- [Character ownership, migration and estates](docs/ownership.md)
- [Saved data and recovery](docs/saved-data.md) — persistence files, backups, and
recovery after a failed save
- [Testing](docs/testing.md) — automated coverage and the dev-only Paper helper
- [Testing](docs/testing.md) — automated coverage and isolated Paper fixtures
- [Default configuration](https://github.com/TF-Minecraft/CompanionPets/blob/main/src/main/resources/config.yml)
- [Plugin commands and permissions](https://github.com/TF-Minecraft/CompanionPets/blob/main/src/main/resources/plugin.yml)

Expand All @@ -29,17 +30,19 @@ for runtime, build, and validation conventions.
Build the source repository with Java **21** and Maven:

```sh
mvn clean verify
python3 ../tlibs/tools/install-plugins.py --pom pom.xml --mode pinned
tfmc-mvn -o -B clean verify
python3 .github/scripts/plugin-artifact.py --jar target/companionpets-main-SNAPSHOT.jar --version main-SNAPSHOT
```

The build uses `io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT` with
`provided` scope. No private jars or shared TFMC plugin artifacts are required.
`provided` scope. TLibs 2.6.0 is a provided shared plugin dependency; no private jars are required.
The plugin entry point is `net.tfminecraft.companionpets.PetsPlugin`.

The descriptor soft-depends on MythicMobs, ModelEngine, ItemsAdder, MMOItems, and
MythicLib so that they load first when installed; none of them is required. The
plugin calls their APIs by reflection: MythicMobs and ModelEngine supply bodies
The descriptor requires TLibs and soft-depends on RPCharacters, MythicMobs, ModelEngine, ItemsAdder, MMOItems, and
MythicLib so that they load first when installed. Property actions need a ready
character provider. The optional presentation/item integrations use reflection:
MythicMobs and ModelEngine supply bodies
and models (`integration/`), and MMOItems and ItemsAdder supply interaction items
and eggs (`item/ItemBridge.java`). MythicLib is only a load-order dependency.
CompanionPets has no runtime dependency on Archaeo, Cooking, or MCPets.
Expand All @@ -51,11 +54,11 @@ verification; the `coverage` profile is only a compatibility alias.

## Testing on a Paper server

The source repository includes a dev-only
[integration helper](docs/testing.md#paper-integration-helper)
that runs once against a real Paper server with the configured providers and
reports `COMPANIONPETS_INTEGRATION PASS` or `FAIL` in the log. It does not
establish correct rendering in a Minecraft client.
The source repository includes an
[isolated ownership fixture](docs/testing.md#isolated-paper-character-ownership-fixture)
that runs against a fresh loopback Paper server and reports `OWNERSHIP_PROOF PASS`
or `FAIL`. It proves native follow/session isolation; client rendering needs a
separate in-game check.

## Builds and releases

Expand Down
51 changes: 51 additions & 0 deletions projects/CompanionPets/docs/ownership.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# CompanionPets character ownership

[CompanionPets](../README.md) · [Saved data](saved-data.md)

Pets and Pet Houses belong to a character. The account UUID remains routing metadata for Minecraft's tame owner and account capacity limits. Switching characters ends hatch/rename/release prompts, training, greetings and fetch work; an inactive character's pet does not follow, teleport to or deliver a fetched toy to the new character. Native swimming, self-defense and safety goals remain available. When `native-combat` is enabled, the two native owner-assist goals require the recorded current owner character; another character on the same account cannot trigger that pet's assistance.

The configured total-pet and outside-pet limits are account-wide. Character rosters show only that character's pets. Hatching, management and new Pet House ownership require a ready character session. Missing identity services refuse property actions.

Carer recognition uses character IDs; changing character does not borrow another character's trust. Pet friendships use pet IDs. Inheritance retains physiology, bond, tricks, favourite toy, pet friendships and the original character identities of human memories.

## Dependencies and compatibility

The build pins TLibs **2.6.0**. RPCharacters supplies ready character sessions and reviewed legacy heirs. New API classes are capability-probed: an older or absent identity API leaves property actions unavailable; an absent estate API leaves ownership with the existing character. Upgrade provider and consumer JARs through a server restart. Plugin reload tools are not supported.

## Legacy ownership migration

After the reviewed legacy-heir directory is ready, each account-owned pet and Pet House receives that account's single reviewed heir. A dead reviewed heir remains the recipient; its estate decides any subsequent inheritance. No active-character or last-played fallback is used.

`ownership-migrations/plan-NNNN.original.yml` is an immutable, verified source copy. `plan-NNNN.yml` contains the original/planned hashes, exact planned bytes and completion marker. These precede the forced file replacement and synchronization of its directory ancestry. Restart retries the stored recipient; conflicting source edits are held for review. Later migration passes may resolve previously missing heirs.

Unknown owners remain inaccessible, retain their saved records and still count toward account limits. Unresolved human-carer pages remain under `legacy-carers` and are inert without freezing an otherwise assigned pet. Root, nested pet, relationship and Pet House metadata survive ordinary saves and restart, including unknown null-valued fields. Unsupported, quoted, null or fractional ownership schema versions, duplicate YAML keys and duplicate Pet House coordinates are refused without rewriting the source. No legacy files are automatically deleted.

## Estates

The `companionpets` estate participant describes pets and Pet Houses for wills. It uses the estate's property recipient. WAITING and FROZEN property stays with the testator. Moving ownership preserves pet/entity IDs and saved gameplay state; inherited overflow is retained.

`estates/<death>-<revision>.yml` records the exact decision, source/recipient account and character, pet/house IDs and completed receipts. Settlement requires the matching death, revision and decision immediately before publication. The participant reconciles at startup and hourly. It waits for this startup's reviewed migration and healthy persistence before creating estate intents; delayed heir readiness cannot seal an empty transfer. An unresolved legacy owner slot on the testator account blocks settlement until staff review resolves its heir; resolved pets retain their normal character authority. Completed IDs remain receipts; repeated settlement does not duplicate pets. A completed receipt that conflicts with remaining testator holdings is BLOCKED for a reviewed new revision, including old empty receipts after late heir resolution. Previously completed IDs that reappear under the testator are held for source/receipt reconciliation and are never transferred again automatically. A stale partial, malformed or conflicting intent is BLOCKED for staff review. Preserve its journal and current save before resolving it.

## Stopped-server rollback

Stop the server cleanly and preserve the complete CompanionPets directory, including deletion/estate journals and the latest progress. Install Python with PyYAML for the source repository tool:

```sh
python3 tools/ownership-rollback.py /path/to/plugins/CompanionPets plan-0001
python3 tools/ownership-rollback.py /path/to/plugins/CompanionPets plan-0001 --apply
```

The first command previews. Applying is accepted only while the current file exactly matches the migration's planned hash and the immutable archive verifies. `pets.pre-rollback.yml` preserves the current file. Any gameplay, estate or later migration changes produce a conflict; reconcile them manually rather than overwriting them. Never remove `pet-deletions.log` to resurrect deleted pets.

An older JAR alone is not a rollback: it cannot enforce character ownership and
discards unknown fields during saves. Once `pets.yml` has changed, the migration
tool refuses rollback. Stay on the character-aware JAR and fix forward, or review
the care, grants, item state and estates that would be lost before restoring a
complete pre-upgrade snapshot and its corresponding JAR while stopped. There is
no automatic conversion of later character data into the old format.

## Verification boundaries

Unit tests exercise character isolation, captured callbacks, reviewed-heir mapping, unknown-field preservation, durable failure/replay and exact estate-intent guards. The loopback-only Paper ownership fixture exercises the actual native FOLLOW_OWNER selector across same-account character switches, water and training transitions; see [testing](testing.md).

Ownership/queue commits and player inventory are separate transactions. Existing egg consumption and physical toy/world effects do not establish arbitrary-crash exactly-once delivery. Preserve the recovery marker, saved carried-toy state and world evidence after interruption; ambiguous effects need staff reconciliation.
4 changes: 3 additions & 1 deletion projects/CompanionPets/docs/saved-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ plugin stops. Each save writes a temporary file and replaces the main file;
| `pets.yml.bak` | The previous valid save. Never activated automatically. |
| `pet-deletions.log` | Durable journal of terminal deletions. |
| `pets-recovery-required` | Marker present while the plugin runs; removed after a successful final save. |
| `ownership-migrations/` | Immutable source copies, planned ownership bytes and completion receipts. |
| `estates/` | Exact death/revision ownership intents and cumulative transfer receipts. |
| `staff-audit.yml.log` | Private log of [staff interventions](staff.md#audit). |

Back up all these files together before manually editing saved data.
Back up all these files together before manually editing saved data. Character ownership, migration and stopped-server rollback are described in the [ownership guide](ownership.md). External edits during a writer session are detected and held instead of overwritten.

## Damaged or missing saves

Expand Down
24 changes: 13 additions & 11 deletions projects/CompanionPets/docs/staff.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ root aliases. Running `/companionpets` shows help and examples.
| `reload` | Reload config and refresh models. Provider problems are logged automatically. |
| `moment <affection/bark/mischief/dig/belly>` | Trigger a moment while looking at your pet; normal care and animation conditions apply. |
| `testpet <type> [name...]` | Spawn a normal pet with every compatible trick learned. No special marker, pause state or cleanup category. |
| `list <player> [pet name...]` | Open that player's pets or a selected pet's read-only profile. Console gets readable names. |
| `find <player> [pet name...]` | Show Pet House, current or last-known location, and missing or duplicate bodies for that player's pets, without loading chunks. |
| `create <player> type=<type> name=<name...> [option=value ...]` | Create a new saved replacement in the owner's Pet House. |
| `list unassigned` | Show pets and Pet Houses held for ownership review without assigning them. |
| `list <character> [pet name...]` | Open that character's pets or a selected pet's read-only profile. Console gets readable names. |
| `find <character> [pet name...]` | Show Pet House, current or last-known location, and missing or duplicate bodies for that character's pets, without loading chunks. |
| `create <character> type=<type> name=<name...> [option=value ...]` | Create a new saved replacement in the owner's Pet House. |
| `egg <type/all> [online-player] [1..64]` | Give configured eggs; omit the recipient in game to receive them yourself. |

```text
Expand All @@ -25,18 +26,20 @@ root aliases. Running `/companionpets` shows help and examples.
/companionpets moment belly
```

## Browsing players and pets
## Browsing characters and pets

Tab completion suggests player names first, then only that player's pet names.
Names can contain spaces. Duplicate pet names are never resolved arbitrarily:
Tab completion suggests owning characters' display names, then that character's
pet names. Creation also offers online account names. The character argument is
one token: use its character UUID when its name contains spaces or is ambiguous.
Pet names can contain spaces. Duplicate pet names are never resolved arbitrarily:
select the pet from `list` to view its identity internally. There is no player
inventory: select the owner using command completion.
inventory.

The selected pet's staff inventory shares the normal pet profile: species,
name, sex, age, needs, bond, personality, favourite toy and learned tricks. It
is read-only, including its trick inventory; renaming, calling, Pet House and
release actions are omitted. No UUIDs or audit snapshots are required or shown
in command help, completion or pet cards. Menu layout and navigation are
release actions are omitted. Character UUIDs can identify owners in commands;
pet cards do not expose audit snapshots. Menu layout and navigation are
described in the [gameplay guide](gameplay.md#menus).

## Creating pets
Expand All @@ -55,8 +58,7 @@ addition to configured default tricks. `tricks=all` teaches every compatible
enabled trick; `tricks=none` adds no extra tricks. Defaults: needs 100, bond 0,
male, new age, generated personality.

An explicitly supplied owner UUID is still accepted for reconstruction of an
unknown or offline player; ordinary browsing and completion use player names.
Specify a known character UUID or a unique single-token living character name. Dead character UUIDs are available for inspection; creation requires a living character. An online account name selects its current ready character. Unknown and ambiguous characters are refused; an arbitrary account UUID cannot create property.
Creation validates options before writing and checks Pet House capacity. The owner
takes the created pet out through their Pet House menu.

Expand Down
29 changes: 28 additions & 1 deletion projects/CompanionPets/docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,34 @@ compatibility alias; ordinary verification already enforces the same gate.

These tests do not establish live Paper behaviour or correct client rendering.

## Paper integration helper
## Isolated Paper character ownership fixture

Build the verified plugin into the local Maven repository, then build the
[loopback ownership probe](https://github.com/TF-Minecraft/CompanionPets/tree/main/integration-tests/ownership):

```sh
tfmc-mvn -o -B clean install
tfmc-mvn -o -B -f integration-tests/ownership/pom.xml clean package
```

Run only in a fresh disposable Paper 1.21.10 server with TLibs 2.6.0, loopback
address `127.0.0.1`, port `25583` and offline mode. Connect `S6PetProbe` using an
offline protocol client. The probe registers a synthetic character provider;
never install it on Main or Dev. It checks actual native follower movement for A,
same-account A→B isolation, active training cleanup, real native owner-assist goals under `native-combat: true`, swimming/self-defense safety, held/unknown
owners and reattachment. It writes
`plugins/CompanionPetsOwnershipProbe/result.json`, logs
`OWNERSHIP_PROOF PASS` only after every check, and stops its disposable server.
Its README documents setup and the actual older-TLibs classloader check.

## Legacy provider integration helper

The broader helper below predates character ownership. CI retains its compilation
gate, but its random account/proxy-player and raw native follower fixtures need a
character-aware update before it can validate current ownership. Use the isolated
ownership probe above for character isolation evidence.



The [helper source](https://github.com/TF-Minecraft/CompanionPets/tree/main/integration-tests)
runs once, starting 240 server ticks after enabling, then disables itself when
Expand Down