-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
There is currently no SDK mechanism for one visitor to interact with another visitor's avatar. Clicking another player's avatar does nothing from an app/game perspective — there's no event fired, no webhook triggered, and no way to open an interactive UI scoped to that visitor-to-visitor interaction.
This is a fundamental gap for any social or multiplayer game built on Topia. Features like inventory trading, viewing another player's stats, sending challenges, gifting items, or any peer-to-peer interaction require hacky workarounds (e.g., "trading blankets" — dropped assets that both players must click to initiate a trade). These workarounds are confusing for users, fragile to implement, and break the spatial intuition of "I want to interact with that person."
A first-class visitor-to-visitor interaction system — click a player's avatar to open an app-controlled side drawer/panel — would unlock an entire category of social gameplay that the platform is uniquely positioned to support.
Current Behavior
- Clicking another visitor's avatar has no app-programmable effect
- There is no
onVisitorClickwebhook or event - Apps cannot open UI panels scoped to a specific visitor pair
- The only way to implement trading or peer interaction is through shared dropped assets ("trading blankets") that both players must independently find and click
Current Workaround: "Trading Blanket" Pattern
1. Player A drops a "trading blanket" asset near themselves
2. Player A clicks the blanket → opens trade UI showing their inventory
3. Player B must walk to the blanket and also click it
4. Player B clicks the blanket → opens trade UI showing their inventory
5. Both players select items, confirm, and the server swaps inventories
Problems:
- Requires both players to coordinate clicking the same physical asset
- No guarantee both players are present — one might walk away
- The blanket can be clicked by anyone, not just the intended trade partner
- No real-time sync between the two players' views
- Confusing UX for kids (ages 7-17): "Why do I need to click a blanket to trade with someone standing right next to me?"
- Multiple blankets in the same area create confusion about which trade is which
Proposed API
1. Visitor Click Event / Webhook
When a visitor clicks another visitor's avatar, fire a webhook to the interactive app with both visitors' credentials:
// New webhook event: visitor-click
// Fired when Visitor A clicks on Visitor B's avatar
{
event: "visitor-click",
clickingVisitor: {
visitorId: "visitor-a-id",
profileId: "profile-a",
displayName: "Player A",
// ... standard visitor credentials
},
targetVisitor: {
visitorId: "visitor-b-id",
profileId: "profile-b",
displayName: "Player B",
},
urlSlug: "my-world",
// ... standard interactive credentials
}2. Open Interactive Drawer for Visitor Pair
A new SDK method to open an interactive side drawer (similar to the existing asset-click drawer) but scoped to a visitor-to-visitor interaction:
// Server-side: open a drawer for the clicking visitor, scoped to the target
await visitor.openInteractionDrawer({
targetVisitorId: "visitor-b-id",
// The drawer loads the app's URL with both visitors' context
// App receives both visitor IDs and can render pair-specific UI
});3. Client-Side Context
The app's iframe would receive additional query parameters identifying the interaction:
// New query params available in the interaction drawer
const interactionType = searchParams.get("interactionType"); // "visitor-click"
const targetVisitorId = searchParams.get("targetVisitorId"); // "visitor-b-id"
const targetProfileId = searchParams.get("targetProfileId"); // "profile-b"
const targetDisplayName = searchParams.get("targetDisplayName"); // "Player B"The app can then render context-specific UI — a trade interface, a profile view, a challenge prompt, etc.
4. Optional: Mutual Interaction (Both Drawers Open)
For features like trading that require both parties, an option to open drawers for both visitors simultaneously:
// Open paired drawers for both visitors (e.g., for trading)
await World.openMutualInteraction({
visitorA: "visitor-a-id",
visitorB: "visitor-b-id",
urlSlug: "my-world",
credentials,
// Both visitors get a drawer opened with each other's context
});Use Cases Unlocked
| Use Case | Current Workaround | With This Feature |
|---|---|---|
| Item Trading | Trading blanket asset both must click | Click player → trade drawer opens for both |
| View Player Profile | No way to do this | Click player → see their level, stats, achievements |
| Challenge / Duel | Drop a "challenge" asset, hope they click it | Click player → "Challenge to a duel?" prompt |
| Gift Items | Drop item near them, hope they pick it up | Click player → "Gift this item?" with confirmation |
| Team Invite | Broadcast toast, no targeting | Click player → "Join my team?" |
| Inspect Inventory | Not possible | Click player → see what they're carrying |
| Social Reactions | Expressions exist but aren't app-controlled | Click player → app-specific reaction menu |
| Mentoring / Help | No mechanism | Click new player → offer to help, share tips |
Lunch Swap Specific
In Lunch Swap, this would enable:
- Direct item swaps — click a player, see their bag, propose a trade (both confirm)
- Meal comparison — click a player who completed today, see their nutrition score vs yours
- Streak flex — click a player to see their streak, level, and achievements
- Targeted item gifting — click a player, select an item from your bag to give them
Security Model
- Proximity requirement — The clicking visitor must be within a configurable radius of the target (e.g., 200 units). Prevents cross-map interactions.
- Opt-in per app — Apps must register for the
visitor-clickevent (similar to registering for asset interactions). Avatars only become clickable in worlds where an app has opted in. - Rate limiting — Prevent spam-clicking by rate-limiting visitor-click events (e.g., max 1 per target per 5 seconds).
- Block/ignore — Respect any existing block/mute settings between visitors.
- Consent for mutual interactions — For
openMutualInteraction, the target visitor should see a prompt ("Player A wants to trade. Accept?") before their drawer opens. No forced UI popups. - App-scoped — The interaction drawer loads the same app that registered for the event. No cross-app interactions.
Implementation Suggestion
Platform Changes
- Click detection — When a visitor clicks another visitor's avatar in the Topia client, check if any interactive app in the world has registered for
visitor-clickevents. - Webhook dispatch — Fire the webhook to the app's server with both visitors' credentials.
- Drawer API — Extend the existing interactive drawer system to support visitor-scoped drawers (in addition to the existing asset-scoped drawers).
- Query params — Pass
interactionType,targetVisitorId,targetProfileId,targetDisplayNameto the app's iframe URL.
SDK Changes
// New event registration (in app configuration or programmatically)
await world.registerInteractiveEvent({
event: "visitor-click",
webhookUrl: "https://my-app.com/api/visitor-interaction",
interactivePublicKey: key,
});
// New method on Visitor class
async openInteractionDrawer(options: {
targetVisitorId: string;
title?: string; // Optional drawer title
height?: number; // Optional drawer height
}): Promise<void>;
// New static method for mutual interactions
static async openMutualInteraction(options: {
visitorAId: string;
visitorBId: string;
urlSlug: string;
credentials: Credentials;
requireConsent?: boolean; // Default: true — target must accept
}): Promise<{ accepted: boolean }>;Type Definitions
interface VisitorClickEvent {
event: "visitor-click";
clickingVisitor: {
visitorId: string;
profileId: string;
displayName: string;
};
targetVisitor: {
visitorId: string;
profileId: string;
displayName: string;
};
urlSlug: string;
distance: number; // Distance between visitors at click time
}
interface InteractionDrawerOptions {
targetVisitorId: string;
title?: string;
height?: number;
}
interface MutualInteractionOptions {
visitorAId: string;
visitorBId: string;
urlSlug: string;
credentials: object;
requireConsent?: boolean;
}Impact
This is arguably the single biggest unlock for social gameplay on the Topia platform. The SDK already excels at spatial presence (visitors in a world) and object interaction (clicking dropped assets). The missing piece is visitor-to-visitor interaction — the ability for players to directly engage with each other through app-controlled UI.
Every multiplayer game or social experience built on Topia would benefit: trading games, RPGs, social deduction games, educational activities with peer interaction, collaborative building, and more. The current workarounds (trading blankets, broadcast toasts, proximity-based auto-matching) are all compromises that degrade the user experience and increase developer complexity.
For the target audience (ages 7-17), direct avatar interaction is the most intuitive social mechanic possible: "I want to interact with that person, so I click on them." No blankets, no buttons, no coordination — just click.