decentraland / decentraland/unity-explorer

Events API | let an event reference a named spawn point of its scene

Open
#9,584 2 comments 0 reactions 0 assignees View on GitHub
2-medium enhancement feature shape-up
Dominant language
C#
Stars
23
Forks
17
Avg merge
2d 17h
Merged PRs (30d)
110

Description

# Events API: let an event reference a named spawn point of its scene

**Type:** feature / cross-team (Events API + Events web app + Explorer client)
**Area:** `decentraland/events` (events.decentraland.org), Explorer `EventsApi` + `RealmNavigation`
**Explorer client size:** trivial — one DTO field plus one argument at the single Jump In call site; the teleport pipeline already supports named spawn points end to end

## Problem

An event only carries `x`, `y` (plus `server`/`world`). That names a parcel, but a parcel is not a
landing spot, so the Explorer has always had to *guess* where inside it to put the player — and every
guess so far has been wrong for someone:

* Landing on the scene's spawn point ignored the event's coordinates entirely: an event at the
Theatre (`0,5`) inside Genesis Plaza dropped players at the plaza entrance (`~0,-1`).
* PR [unity-explorer#8942](https://github.com/decentraland/unity-explorer/pull/8942) fixed that by
landing at the geometric **centre** of the event's parcel — which is exactly where a small scene
tends to stand its centrepiece asset. Players spawned on top of (or inside) the asset the event
was about ([unity-explorer#9546](https://github.com/decentraland/unity-explorer/issues/9546)).
* PR [unity-explorer#9567](https://github.com/decentraland/unity-explorer/pull/9567) fixed *that*
with a client-side heuristic: if the scene declares a named spawn point whose area covers the
event's parcel, land on it; otherwise keep the parcel centre.

The heuristic resolves every live event correctly today, but it is still the client guessing the
organizer's intent from geometry. It cannot cover:

* an event parcel that holds **no** spawn point — the player still gets the invented parcel-centre
landing, "settled" by a physics floor probe (`SnapToSceneFloor`, 15 m step-up tolerance) that can
place them on top of whatever stands there;
* a parcel covered by **several** spawn points — the client picks one by declaration order, the
organizer has no say;
* an organizer who wants players to land at a spawn point **outside** the event parcel (e.g. a
queue/lobby area for a stage event).

The missing piece was already named in #8942's own description:

> A cleaner long-term option (out of scope here) is author-defined **named spawn points** in
> `scene.json` that an event/place can reference.

Both halves of that option now exist — `scene.json` spawn points have an optional `name`, and since
PR [unity-explorer#9369](https://github.com/decentraland/unity-explorer/pull/9369) the Explorer
teleport pipeline accepts a `spawnPointName` and resolves it with correct anchoring, `cameraTarget`
look-at, and graceful fallback when the name doesn't match. The only link still missing is the
Events API carrying the name from the organizer to the client.

## Proposal

Add an optional **spawn point name** to the event model, flowing organizer → API → client:

1. **API (`decentraland/events`):** a new optional field on the event entity — suggested
`spawn_point_name: string | null` (snake_case like the rest of the wire format) — accepted on
event create/edit and returned by `GET /api/events`. Absent/null means "no preference", which
must keep today's behaviour exactly.
2. **Events web app (submit/edit form):** a field to pick the spawn point. Ideally a dropdown
populated from the deployed scene's metadata for the entered coordinates (the Catalyst
`POST /content/entities/active` response carries `metadata.spawnPoints[].name`), with free-text
as the minimum viable version — an unknown name degrades gracefully on the client (falls back to
the default spawn selection, see `FallBackToDefaultSelectionWhenNameNotMatched` in
`TeleportUtilsShould`).
3. **Explorer client:** deserialize the field in `EventDTO` and pass it at the single Jump In call
site (`EventCardActionsController`) into the existing
`IRealmNavigator.TeleportToParcelAsync(parcel, ct, isLocal, landOnParcel, spawnPointName)`
overload. No pipeline changes.

Precedence on the client, most explicit wins:

| Event data | Landing |
|---|---|
| `spawn_point_name` set | that spawn point, via the existing named-spawn-point path |
| not set, a named spawn point covers the event parcel | that spawn point (the #9567 heuristic, unchanged) |
| not set, no spawn point in the parcel | parcel centre + floor probe (the #8942 behaviour, unchanged) |

This also gives organizers the "flexible behaviour without redeploying the scene" property the
parcel coordinates were informally used for: one scene, different events, different landings — now
deterministic instead of guessed.

### Non-goals

* No change to `scene.json` — spawn point names already exist there.
* No validation hard-failure when the name doesn't match the deployed scene (scenes redeploy
independently of events; the client fallback handles drift).
* The `landOnParcel` plumbing refactor is tracked separately in
[unity-explorer#9583](https://github.com/decentraland/unity-explorer/issues/9583); this ticket
neither depends on it nor blocks it.

## Acceptance criteria

- [ ] `GET /api/events` returns `spawn_point_name` (null when unset) and create/edit accept it
- [ ] Events web form lets an organizer set/clear the spawn point for a Genesis City event
- [ ] Explorer Jump In on an event with `spawn_point_name` lands on that spawn point, honouring its
`cameraTarget`
- [ ] Explorer Jump In on an event without the field behaves exactly as today (heuristic, then
parcel centre)
- [ ] An event whose `spawn_point_name` no longer matches the deployed scene falls back to the
scene's default spawn selection instead of erroring

## History

| When | What | Where |
|---|---|---|
| — | `scene.json` `spawnPoints[]` support optional `name`; teleport docs | [scene metadata docs](https://docs.decentraland.org/creator/development-guide/sdk7/scene-metadata/#spawn-location) |
| 2026-06-15 | Events Jump In lands on the event parcel (centre) via `landOnParcel`; the "named spawn point an event can reference" option called out as the cleaner long-term fix | [unity-explorer#8942](https://github.com/decentraland/unity-explorer/pull/8942) |
| 2026-06 | `spawnPointName` threaded through the whole teleport pipeline (deeplink overrides): name matching, base-parcel anchoring, `cameraTarget`, fallback on unknown name | [unity-explorer#9369](https://github.com/decentraland/unity-explorer/pull/9369) |
| 2026-07 | Bug report: Events Jump In lands players inside the scene's centrepiece asset | [unity-explorer#9546](https://github.com/decentraland/unity-explorer/issues/9546) |
| 2026-08-03 | Client-side heuristic: land on the named spawn point covering the event's parcel, if any | [unity-explorer#9567](https://github.com/decentraland/unity-explorer/pull/9567) |
| 2026-08-04 | Tech-debt ticket: replace the `landOnParcel` flag with an explicit teleport destination | [unity-explorer#9583](https://github.com/decentraland/unity-explorer/issues/9583) |

## Links

* Events API: `https://events.decentraland.org/api/events` — [decentraland/events](https://github.com/decentraland/events)
* Explorer DTO: `Explorer/Assets/DCL/EventsApi/EventDTO.cs`
* Explorer Jump In call site: `Explorer/Assets/DCL/Events/EventCardActionsController.cs` (the only `landOnParcel: true` caller)
* Named spawn point resolution: `Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/TeleportUtils.cs` (`PickTargetWithOffset`)

Contributor guide

Open the contributing guide

Research direction

Start with Explorer/Assets/DCL/EventsApi/EventDTO.cs and the single Jump In call site in Explorer/Assets/DCL/Events/EventCardActionsController.cs, then read the existing named-spawn handling in Explorer/Assets/DCL/Infrastructure/SceneLifeCycle/TeleportUtils.cs and its TeleportUtilsShould tests. Trace the event field through the Events API and web form. Done means the field is accepted, returned, selectable, passed to teleport, and preserves fallback behavior when absent or unmatched.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, desktop, full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.