Skip to content

TrainerOS Link: define adapter-driven system activities independently of in-game multiplayer #109

Open

Description

@EriArk

Part of #98. Owner clarification: networked features of TrainerOS itself are a first-class product track, separate from multiplayer inside a launched game. This corrects the earlier game-launch-heavy framing of #98/#104–#107.

Product distinction

TrainerOS has two independent network consumers:

  1. System Link activities — TrainerOS uses exact game adapters to let users trade, gift, buy/sell for in-game currency, or participate in another supported OS-owned interaction. The original game/emulator does not need to run or implement multiplayer.
  2. In-game multiplayer — a game's LAN/online mode or an emulator's netplay; In-game multiplayer: prove one exact online game/runtime adapter, separate from TrainerOS Link #107 owns this separate runtime integration.

Existing Pokémon Link is the first example of the first category, not an emulator-netplay workaround. Later games should gain their own appropriate system activities through adapters. An OS-hosted battle/simulation also belongs to the first category even though two humans participate.

Neither category implies support for the other. A game may support either, both or neither. Do not use a single supportsMultiplayer flag or require a runtime-netplay provider before exposing a system exchange.

User experience

Keep the existing small social UI. Contextual actions may look like:

Friend / conversation / compatible game feature
    Chat
    Voice
    Exchange…       → native TrainerOS offer/review UI
    Gift…           → native TrainerOS offer/review UI
    Other activity… → an explicitly supported adapter activity
    Play together   → launch actual in-game multiplayer, when supported

These are examples, not a requirement to display every action for every title. Show only effective, compatible actions. Reuse the same native activity from a friend/conversation entry and from the existing Link/game-family surface; do not build duplicate transaction UIs. No new primary tab, marketplace, global inventory or mandatory always-online profile.

Audit and evolve the existing boundary

Start with Emerald Link, Nearby Play, #42/#45 and #89/#92. Reuse their semantic records, exact-build validation, protected host transactions and session acceptance. Do not rewrite working Emerald code just to create a universal framework.

Define the smallest versioned system-activity capability contract that composes existing adapters. It should describe, where needed:

  • namespaced activity ID and protocol/schema version;
  • exact supported source/destination builds, adapter versions and directional compatibility;
  • semantic object/currency/ruleset schemas, participant roles and supported counts;
  • read-only, local-write or bilateral-transaction effects;
  • save readiness, source revision, capacity and policy requirements;
  • minimum transport properties, payload bounds and recovery semantics;
  • bounded semantic offer, validation and result types;
  • presentation/action metadata consumed by the host or franchise experience, not arbitrary remote QML.

Do not prescribe final interface names or a new dynamic plugin loader before the code audit. Activity-specific models and UI extensions are allowed: not every game's item, character or interaction is a Pokémon trade.

Responsibilities

Game adapter / activity rules
    understands the exact game's objects and valid transformations
                ↕ bounded semantic input/output
TrainerOS activity + transaction host
    identity, permission, session, UI, reservations, journal, commit/recovery
                ↕ versioned activity envelopes
Shared connection / delivery provider
    nearby LAN or verified Direct / approved Fluxer route / direct P2P / relay

Adapters do not log into Fluxer, manage sockets, read arbitrary files, spawn processes or commit saves themselves. QML does not parse binary saves or execute incoming commands. The host owns local paths, stable reads, protection backups, revision checks, replacement and readback.

Provider-account identity, local Trainer identity and game-native origin fields remain distinct. Transport binding may use Fluxer identity for online peers, but nearby offline Link must continue without a Fluxer account. Preserve existing explicit local-pairing trust limits.

Cross-game compatibility is explicit

Two adapters both advertising exchange is not proof their objects are interchangeable. Cross-title transfer requires an explicit, verified conversion/import contract preserving required identity and semantics. Reject unknown schema/build/ruleset combinations before any reservation or write. Do not invent exchange rates between unrelated games or merge currencies into a TrainerOS economy.

Publish only coarse capabilities before an invitation is accepted. Do not automatically expose a user's collection, balances, save contents or full library to every friend. Offers reveal only the selected data required for review.

Integrity and lifecycle

Friendship, connection consent, activity consent and approval of the exact final offer are separate. A changed offer invalidates both approvals. Bind operations to local owner, selected save lineage/revision, exact participants and activity/transaction IDs. Two devices using the same identity must not become duplicate recipients of a gift; document the existing identity-cloning limitation rather than promising global anti-cheat.

Apply #75 centrally. Prevent writes while the relevant game/save is active; ask for safe return using #49 where needed. Do not require launching or installing a netplay runtime to perform a system activity whose own prerequisites are otherwise satisfied.

Transport delivery, chat history and a chat reaction are never proof of successful save settlement. Keep durable #45 recovery, idempotent replay and bilateral receipts below the UI. A timeout cannot prove that the peer did not commit. Do not automatically perform a one-sided rollback, delete unresolved journals or promise non-blocking atomic settlement through a network partition.

Scope and dependency

This issue owns the reusable activity boundary and its existing Emerald mapping. #104 owns shared invitations; #105 evaluates suitable delivery per traffic class; #106 owns direct/relay transport where needed. System activities may use a proven lower-rate Fluxer delivery path without waiting for #106's full P2P stack. They do not depend on #107, virtual LAN or live voice.

A separate online Emerald increment should prove the first real OS activity. Before calling the contract generic, exercise a materially different synthetic adapter/schema so shared code cannot depend on Pokémon field names. This is architecture/test evidence, not a claim that a second real game is supported.

Acceptance

  • System activities and in-game multiplayer have independent capabilities, entry points and release gates.
  • Existing Emerald Link maps to this boundary without changing its game/save semantics.
  • An eligible system activity works without starting the original game or an emulator-netplay session.
  • A synthetic non-Pokémon activity proves schema/behavior extensibility without title checks in shared networking/QML.
  • Unknown cross-adapter pairs are rejected; no implicit universal inventory or currency appears.
  • Friends/chat and the native game-feature entry open the same activity implementation.
  • Owner, consent, revision, read-only and recovery safeguards remain enforced below presentation.
  • Local offline Link remains usable and device-specific Direct safety policy stays unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions