Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9c7228e
docs: promote Building for Mobile to top-level section, rename to Bui…
rodrigo685 Jul 13, 2026
29778a2
docs: remove desktop-scale-3x tip from onscreen-ui mobile hint
rodrigo685 Jul 13, 2026
b3dd650
docs: add Hardware Requirements page for mobile
rodrigo685 Jul 13, 2026
9fc2b78
docs: remove TestFlight beta hint from building-for-mobile overview
rodrigo685 Jul 13, 2026
9e2d5e6
docs: remove TestFlight beta hint and add mobile screenshot to mobile…
rodrigo685 Jul 13, 2026
6652d33
Add files via upload
rodrigo685 Jul 13, 2026
84e2b9c
docs: add Missing Features page under Build for Mobile
rodrigo685 Jul 13, 2026
4fc2b62
docs: add Sample Scenes page under Build for Mobile
rodrigo685 Jul 13, 2026
d9733c9
docs: add mobile app screenshot to Build for Mobile overview
rodrigo685 Jul 13, 2026
b0b0554
Add files via upload
rodrigo685 Jul 13, 2026
e6f7c09
docs: add Optimize Performance page and update nav
rodrigo685 Jul 13, 2026
c434c9d
docs: fix optimize-performance image placement and preview steps
rodrigo685 Jul 13, 2026
83206a1
docs: move scene limits image to after preview steps
rodrigo685 Jul 13, 2026
c048074
docs: restructure Build for Mobile into Mobile Client / Develop / Pub…
rodrigo685 Jul 13, 2026
070480c
fix: correct image paths — images are at repo root, not .gitbook/assets
rodrigo685 Jul 13, 2026
9d60350
docs: overview/performance/get-featured edits per review feedback
rodrigo685 Jul 13, 2026
71d9ebf
refactor: move build-for-mobile files from sdk7/ to top-level creator…
rodrigo685 Jul 15, 2026
a8e509a
docs: address nearnshaw review comments
rodrigo685 Jul 15, 2026
d0ebcbd
docs: consolidate performance hints, update isMobile() description
rodrigo685 Jul 15, 2026
2dbb14f
Add files via upload
rodrigo685 Jul 15, 2026
dd465b3
docs: update overview checklist + publish section intro
rodrigo685 Jul 15, 2026
eab6268
docs: update Performance soft/hard limits in mobile scene limits table
rodrigo685 Jul 15, 2026
ba4178b
docs: scale mobile-featured image to 33% in get-featured page
rodrigo685 Jul 15, 2026
5bf0790
docs: update Performance limits — soft 90%, hard 85%
rodrigo685 Jul 15, 2026
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
27 changes: 18 additions & 9 deletions creator/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,6 @@
* [Make Discoverable](sdk7/publishing/make-discoverable.md)
* [Publishing Options](sdk7/publishing/publishing-options.md)
* [Publishing](sdk7/publishing/publishing.md)
* [Building for Mobile](sdk7/building-for-mobile/)
* [Overview](sdk7/building-for-mobile/README.md)
* [Detect the platform](sdk7/building-for-mobile/detect-platform.md)
* [Preview on mobile](sdk7/building-for-mobile/preview-on-mobile.md)
* [Mobile safe area](sdk7/building-for-mobile/safe-area.md)
* [UI best practices](sdk7/building-for-mobile/ui-best-practices.md)
* [Input on mobile](sdk7/building-for-mobile/input-on-mobile.md)
* [Get featured](sdk7/building-for-mobile/get-featured.md)
* [iOS curation](sdk7/building-for-mobile/ios-curation.md)
* [Interactivity](sdk7/interactivity/)
* [Button Events](sdk7/interactivity/button-events/)
* [Click Events](sdk7/interactivity/button-events/click-events.md)
Expand Down Expand Up @@ -186,6 +177,24 @@
* [Scene Analytics](sdk7/other/scene-analytics.md)
* [Migrate Legacy SDK6 Scenes](sdk7/other/migrate-legacy-sdk6-scenes.md)

## Build for Mobile

* [Mobile Client](build-for-mobile/mobile-client/)
* [Overview](build-for-mobile/mobile-client/overview.md)
* [Sample Scenes](build-for-mobile/mobile-client/sample-scenes.md)
* [Missing Features](build-for-mobile/mobile-client/missing-features.md)
* [Hardware Requirements](build-for-mobile/mobile-client/hardware-requirements.md)
* [Develop](build-for-mobile/develop/)
* [Detect the platform](build-for-mobile/develop/detect-platform.md)
* [Preview on Mobile](build-for-mobile/develop/preview-on-mobile.md)
* [Mobile Safe Area](build-for-mobile/develop/safe-area.md)
* [UI Best Practices](build-for-mobile/develop/ui-best-practices.md)
* [Input on Mobile](build-for-mobile/develop/input-on-mobile.md)
* [Performance](build-for-mobile/develop/optimize-performance.md)
* [Publish](build-for-mobile/publish/)
* [Get Featured](build-for-mobile/publish/get-featured.md)
* [iOS Curation](build-for-mobile/publish/ios-curation.md)

## 3D Modeling and Animations

* [3D Models](3d-modeling/3d-models.md)
Expand Down
8 changes: 8 additions & 0 deletions creator/build-for-mobile/develop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Develop

- [Detect the platform](detect-platform.md): Detect whether your scene is running on mobile, desktop, or web.
- [Preview on mobile](preview-on-mobile.md): Preview your scene on a real mobile device from the Creator Hub or the CLI.
- [Mobile safe area](safe-area.md): Where scene UI can safely live on mobile — clear of the system HUD and the device's hardware-reserved margins.
- [UI best practices](ui-best-practices.md): DOs and DON'Ts for designing scene UIs that work well on mobile.
- [Input on mobile](input-on-mobile.md): How input actions map to touch on the Decentraland mobile client.
- [Performance](optimize-performance.md): Mobile scene limits, how to preview them in Creator Hub, and how to hit performance targets.
90 changes: 90 additions & 0 deletions creator/build-for-mobile/develop/detect-platform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
description: Detect whether your scene is running on mobile, desktop, or web.
---

# Detect the Platform from Code

Use the `isMobile()` function to adapt your UI, controls, and gameplay specifically for mobile. This is the recommended way to deliver a great experience across all clients without forking your scene logic entirely.

## Available functions

```ts
import { getPlatform, isMobile, isDesktop, isWeb } from '@dcl/sdk/platform'
```

* **`getPlatform()`** — returns the current platform as `'mobile' | 'desktop' | 'web' | null`. Returns `null` until the explorer has reported its platform back to the scene (this happens shortly after the scene starts).
* **`isMobile()`** — returns `true` if the player is on the mobile client.
* **`isDesktop()`** — returns `true` if the player is on the desktop client.
* **`isWeb()`** — returns `true` if the player is on the web client.

{% hint style="warning" %}
**📔 Note**: These functions read a value that is populated asynchronously when the scene starts, and nothing guarantees it's already available by the time `main()` runs. If you call them too early, they may still return `null` / `false`. To be safe, defer any platform-dependent setup until `getPlatform()` returns something other than `null`, for example by checking inside a system:

```ts
import { engine } from '@dcl/sdk/ecs'
import { getPlatform } from '@dcl/sdk/platform'

function platformCheckSystem() {
if (getPlatform() === null) return
engine.removeSystem(platformCheckSystem)
setupUI()
}

engine.addSystem(platformCheckSystem)
```
{% endhint %}

## Branch your UI by platform

A common pattern is to set up a different UI for mobile and desktop players:

```ts
import { isMobile, isDesktop } from '@dcl/sdk/platform'

function setupUI() {
if (isMobile()) {
// Larger buttons, simpler layout for touch
createMobileUI()
} else if (isDesktop()) {
// Denser layout tuned for keyboard and mouse
createDesktopUI()
}
}
```

You can also use the same pattern to:

* Show or hide on-screen instructions tailored to each input method.
* Replace small clickable elements with larger touch targets on mobile.
* Disable input bindings that are not easily available on mobile (see [Input on mobile](input-on-mobile.md)).

## Checking the raw platform value

If you need to handle multiple platforms in a single switch, use `getPlatform()`:

```ts
import { getPlatform } from '@dcl/sdk/platform'

const platform = getPlatform()

switch (platform) {
case 'mobile':
// mobile-specific behavior
break
case 'desktop':
// desktop-specific behavior
break
case 'web':
// web-specific behavior
break
case null:
// platform not yet known
break
}
```

## Related

* [Mobile safe area](safe-area.md)
* [UI best practices for mobile](ui-best-practices.md)
* [On-screen UI](../../sdk7/2d-ui/onscreen-ui.md)
53 changes: 53 additions & 0 deletions creator/build-for-mobile/develop/input-on-mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: How input actions map to touch on the Decentraland mobile client.
---

# Input on Mobile

Decentraland's input system is designed to be device-agnostic. The same `InputAction` enum that the SDK exposes on desktop is also routed from the on-screen controls on mobile, so most scenes work without any changes. There are, however, a few rules and gotchas worth knowing when you're building for touch.

For the full input model, see [Click events](../../sdk7/interactivity/button-events/click-events.md). This page focuses on what is mobile-specific.

## What touch maps to

Every `InputAction` that exists on desktop is also available on the mobile client — the on-screen controls simply route touch to the same SDK inputs. This means any scene that relies on the standard `InputAction` values will work on mobile out of the box.

The on-screen controls map as follows:

* **On-screen joystick** — drives `IA_FORWARD` / `IA_BACKWARD` / `IA_LEFT` / `IA_RIGHT` and avatar movement.
* **Interaction button (bottom right)** — fires `IA_POINTER` (the left mouse button on desktop) against whatever the player is aiming at.
* **E button** — fires `IA_PRIMARY` (the `E` key on desktop).
* **F button** — fires `IA_SECONDARY` (the `F` key on desktop).
* **Jump button** — fires `IA_JUMP` (the `Space` key on desktop). This is the largest button on the HUD and is always easy to reach.
* **1 / 2 / 3 / 4 buttons** — fire `IA_ACTION_3` / `IA_ACTION_4` / `IA_ACTION_5` / `IA_ACTION_6` respectively. These live behind a secondary menu (see below).
* **Camera drag** — rotates the camera; not exposed as an `InputAction`.

## Inputs to avoid for key actions on mobile

All `InputAction` values are reachable on mobile, but `IA_ACTION_3`–`IA_ACTION_6` (the `1`/`2`/`3`/`4` buttons) are tucked away behind a secondary menu and are **not easily reachable during gameplay**. If your scene uses them as primary actions, mobile players will not be able to trigger them comfortably.

Avoid binding key actions to:

* `IA_ACTION_3` — the `1` key on desktop / `1` button on mobile
* `IA_ACTION_4` — the `2` key on desktop / `2` button on mobile
* `IA_ACTION_5` — the `3` key on desktop / `3` button on mobile
* `IA_ACTION_6` — the `4` key on desktop / `4` button on mobile

Prefer instead:

* `IA_POINTER` for the main tap / interaction button
* `IA_PRIMARY` for the E button action
* `IA_SECONDARY` for the F button action
* `IA_JUMP` when an action maps naturally to jumping (it's the largest and most reachable button on the mobile HUD)
* Proximity-based triggers (see [Proximity Events](../../sdk7/interactivity/button-events/proximity-events.md)) when an action should fire automatically as the player approaches an entity

## Cursor lock

The [`PointerLock` component](../../sdk7/interactivity/button-events/click-events.md#lock-or-unlock-the-cursor) is a desktop-client concept (locked vs. unlocked mouse cursor). It does not apply to touch on mobile and is safe to leave in your scene — it has no effect there.

## Related

* [Click events](../../sdk7/interactivity/button-events/click-events.md)
* [Proximity Events](../../sdk7/interactivity/button-events/proximity-events.md)
* [Detect the platform from code](detect-platform.md)
* [UI best practices for mobile](ui-best-practices.md)
42 changes: 42 additions & 0 deletions creator/build-for-mobile/develop/optimize-performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Optimize Performance

Mobile devices have tighter resource constraints than desktop or web. Understanding the mobile scene limits and how to preview them helps you ship a scene that runs smoothly for the widest audience.

## Mobile Scene Limits

The table below shows the limits enforced when running on mobile. Reaching a **soft limit** triggers a warning in the performance panel; reaching a **hard limit** blocks the scene from loading.

| Metric | Soft Limit | Hard Limit |
| --- | --- | --- |
| Triangles | 1,000,000 | 1,200,000 |
| Entities | 4,800 | 6,000 |
| Meshes (bodies) | 2,400 | 3,000 |
| Geometries | 1,000 | 2,000 |
| Materials | 400 | 500 |
| Textures | 400 | 500 |
| Colliders | 1,200 | 1,500 |
| Content size | 120 MB | 150 MB |
| External content | 40 MB | 50 MB |
| Memory (process RSS) | 1,638 MB | 2,048 MB |
| Draw calls | 1,000 | 2,000 |
| Performance (higher is better) | 90% | 85% |

## Preview Mobile Performance

You can check your scene’s mobile performance directly from **Creator Hub** without deploying to a physical device.

1. Open your scene in **Creator Hub**.
2. Select Preview > Show QR Code for Mobile
3. Open the **Scene Limits Preview** from the top right icon in your phone (monitor with statistics in red).

![Mobile scene limits panel in Creator Hub](../../../mobile_scene_limits.png)

{% hint style="warning" %}
**Keep Performance above 90% on High Graphics**

The **Performance** value is a percentage of the FPS budget set by the active graphic profile. A score of **100%** means the scene is hitting the full FPS target.

Always test on a mid-spec device like the **Samsung Galaxy A54** and aim for a **Performance score above 90% on the High graphic profile**. This ensures a smooth experience for the majority of mobile players. See [Hardware Requirements](../mobile-client/hardware-requirements.md) for reference devices.

You can change the graphic profile from **In-Game Menu → Settings → Graphics → set Dynamic Graphics to Off → switch Profiles**.
{% endhint %}
52 changes: 52 additions & 0 deletions creator/build-for-mobile/develop/preview-on-mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
description: Preview your scene on a real mobile device from the Creator Hub or the CLI.
---

# Preview Your Scene on Mobile

You can preview your scene directly on the Decentraland mobile app from the Creator Hub or from the command line. This is the only reliable way to confirm that your UI, input handling, and performance hold up on a real device.

## Prerequisites

* The Decentraland mobile app installed on your phone — see the [download links](../mobile-client/overview.md#get-the-mobile-app).
* The phone and your development machine must be on the **same local network** (Wi-Fi). The preview is served from your computer; the QR code links to a LAN URL.

## Option A — From the Creator Hub

1. Open your scene in the Creator Hub.
2. Click the dropdown next to the **Preview** button and choose **Show QR Code for Mobile**.
3. Scan the displayed QR code with your phone's camera. The link opens the Decentraland mobile app and loads your scene preview.

<figure><img src="../../../.gitbook/assets/mobile-preview-creator-hub.png" alt="Creator Hub preview dropdown with the Show QR Code for Mobile option"><figcaption><p>The "Show QR Code for Mobile" option in the Creator Hub preview dropdown.</p></figcaption></figure>

## Option B — From the command line

From the root of your scene project, run:

```bash
npm run start -- --mobile
```

The CLI prints a QR code in the terminal that points to your scene's LAN URL. Scan it with your phone to load the scene in the Decentraland mobile app.

<figure><img src="../../../.gitbook/assets/mobile-preview-cli-qr.png" alt="QR code printed by the Decentraland CLI for mobile preview"><figcaption><p>A QR code printed by <code>npm run start -- --mobile</code>. Scan it with your phone to open the scene in the Decentraland mobile app.</p></figcaption></figure>

{% hint style="info" %}
**💡 Tip**: When you pass `--mobile`, the desktop explorer is not also launched. If you want to test on both at once, run `npm run start` in one terminal for desktop and `npm run start -- --mobile` in another for mobile.
{% endhint %}

## Hot reload

Just like with desktop preview, the mobile preview reloads automatically when you change scene files. You don't need to re-scan the QR code after every edit.

## Troubleshooting

* **QR code doesn't open the app** — make sure the Decentraland app is installed and that you've opened it at least once on the device.
* **Phone can't reach the preview server** — confirm the phone and the dev machine are on the same Wi-Fi network. Some corporate networks isolate clients; use a personal hotspot or a different network if so.
* **Scene loads on the phone but looks different from desktop** — that is expected. Use this as the moment to validate your [safe area](safe-area.md), [UI sizing](ui-best-practices.md#sizing), and [input bindings](input-on-mobile.md).

## Related

* [Preview Your Scene](../../sdk7/getting-started/preview-scene.md)
* [Using the CLI](../../sdk7/getting-started/using-the-cli.md)
* [Get featured on mobile Discover](../publish/get-featured.md)
Loading