DreamPark Developer Portal
Download SDK Sign In MyDreamPark

Build downloadable theme parks for the real world.

The DreamPark SDK is a Unity 6 project on GitHub. Clone it, open it, set a content ID, build your attraction, script gameplay in Lua, and publish from the editor — your build downloads to physical DreamPark venues from there.

Public on GitHub

Clone the repo and open in Unity 6. No approval gate to get started.

Lua-first scripting

XLua maps Unity's API 1:1, and scripts push over-the-air without rebuilding.

One-click publish

The editor's Content Uploader packages and ships your build to venues.

Best practices

Read this first — it's the short list that separates attractions that thrive at real venues from ones that don't:

Overview

DreamPark is a chain of mixed-reality theme parks. Guests show up, put on a Quest 3 and a DreamBand wristband, and walk into your attraction in a real physical room. Your build downloads to the venue, runs on the headset, and earns you a share of every play.

The SDK is the framework you use to build those attractions. It's a complete Unity 6 project — clone it, open it, and your content lives under Assets/Content/. Everything else in the project is platform plumbing that keeps your build compatible with venue hardware: wristbands, headsets, payment kiosks, networking, and so on. The SDK is released alongside the main DreamPark app and you pull updates when we ship them.

Coming from at-home VR or indie? A few things are different in a real venue. Guests are paying customers playing in a shared physical room for somewhere between five minutes and an hour. They can't reset, restart, or troubleshoot — whatever ships has to just work, every time, for everyone. Best practices above covers the small set of things worth knowing up front.

Quick start

  1. Clone the SDK from GitHub. The repo is public — grab it and go. Open it in Unity 6.
  2. Set your content ID. On first launch, a setup popup asks you to pick a unique identifier for your attraction (e.g. coincollector). This renames the starter folder under Assets/Content/ for you.
  3. Open Template.unity under Assets/Content/<your-id>/1. Scenes/. Press Play — you're in the starter scene.
  4. Create your attraction. Drop an AttractionTemplate, pick a size, drag in props. More below.
  5. Script gameplay in Lua with LuaBehaviour — it does everything MonoBehaviour does, and releases instantly. More below.
  6. Test on a Quest 3. Build to a Quest 3 or Quest 3S for real-hardware iteration.
  7. Publish. Open DreamPark → Content Uploader, sign in with your developer account, fill in name/description/release notes/logo, and click Compile & Upload. More below.

Requirements

Project structure

The project is one Unity 6 solution. Everything you build lives under Assets/Content/<your-content-id>/; everything else is the SDK and Unity itself. Hover the highlighted rows to see what each core piece does.

Assets/
DreamPark/SDK source, refreshed when you update — don't modify
Content/
<your-content-id>/the folder name IS your content ID
1. Scenes/
Template.unityyour editing scene
2. Features/1. Player/
Player.prefab Player The persistent player object. It survives across attractions — global systems like score, audio managers, and park-wide state live here as LuaBehaviours, and get injected into your props.
Prefabs/
A_TestAttraction.prefab Attraction A self-contained experience with an AttractionTemplate on its root — an arcade game, boss battle, or challenge course. It auto-adds a GameArea (guest presence, and the playtime your revenue share is based on) and a MusicArea.
P_TestProp.prefab Prop An interactive object with a PropTemplate on its root — coins, hammers, hazards, decorations. Props live inside attractions, and operators can also place them between attractions around the park.
P_Enemy.prefab
Previews/auto-generated HD tile art
Scripts/your Lua (*.lua.txt)
ThirdParty/shipped third-party assets
ThirdPartyLocal/import staging — gitignored, not shipped

Your content is made of three pieces: a persistent Player, your Attractions (A_*.prefab), and their Props (P_*.prefab). Multiple content folders can coexist in one project — each is its own independent package, and the Content Uploader's dropdown picks which one to publish.

Set your content ID

The first time you open the project, the Content ID Setup popup walks you through picking a unique identifier for your attraction. The ID:

The popup renames the starter folder from the template placeholder to Assets/Content/<your-id>/ and keeps Unity GUIDs intact so nothing in the scene breaks. Pick something short and final — this is the canonical ID used to publish your attraction.

If the popup ever reappears, it means the project doesn't have a valid content ID set. Fill it in again and you're back on track.

Create your first Attraction

Open Template.unity under Assets/Content/<your-id>/1. Scenes/. You'll see a blank arena — that's your canvas.

An Attraction is a prefab with an AttractionTemplate component on its root (naming convention: A_MyAttraction.prefab). The template auto-attaches a GameArea (the playable boundary that detects guests — and measures the playtime your revenue share is based on) and a MusicArea (an audio zone). Drop one into the scene, then pick a size from the inspector — they range from Micro (a few square meters) up to Jumbo, with a Custom option for anything in between.

The Attraction template includes inspector toggles to auto-generate floor and ceiling meshes, so you don't have to model them yourself unless you want to. When it's ready, save it as a prefab under Assets/Content/<your-id>/Prefabs/ — an HD preview is auto-generated for every attraction, so it shows up in the app with tile art automatically. Open A_TestAttraction in the starter project to see a working example.

Create your first Prop

Props are interactive bits between attractions — they let operators fill tight hallways with collectable coins, or add environmental detail around core attractions. A Prop is a prefab with a PropTemplate component on its root (naming convention: P_MyProp.prefab), which carries a category (Coin, Block, Hazard, Decoration, etc.) and a calibration Y-offset so the prop sits correctly on the floor at real venues.

Props also work inside your attractions: drag a prop prefab in, position it, and it's hooked in. Behind the scenes the SDK regenerates collision avoidance data (used for hand tracking and player movement) whenever you change the attraction or its props — you don't manage that yourself. HD previews are auto-generated for props too.

The starter project ships example props under Assets/Content/<your-id>/Prefabs/ — open P_Enemy and P_TestProp to see how working props are put together.

Customize your Player

Player.prefab (under Assets/Content/<your-id>/2. Features/) is the root player object, already placed and wired into the Template scene. It persists across attractions, so anything you attach to it survives scene loads. Use it for things that should outlive a single attraction — global score state, audio managers, park-wide systems — attached as LuaBehaviours and injected into your props.

About the DreamBand. The DreamBand is DreamPark's core in-game interface — it displays the guest's profile, Wi-Fi status, DreamPoints, and video recording across all content experiences, and it is not a developer-edited component. If you build UI for points, we recommend building around the band, not on top of it: diegetic world-space readouts on props, scoreboards in the room, effects near the wrist.

Scripting in Lua

Write your gameplay in Lua. All of it. The SDK is built around XLua, and there is nothing you can do in a MonoBehaviour that you can't do in a LuaBehaviour:

Add a LuaBehaviour component to any GameObject and point it at a .lua.txt file under Content/<YourGame>/Scripts/:

lua-- coin.lua.txt: a spinning coin any hand can collect
local rotateSpeed = 90  -- degrees / sec

function update()
    self.transform:Rotate(CS.UnityEngine.Vector3.up * rotateSpeed * CS.UnityEngine.Time.deltaTime)
end

function ontriggerenter(other)
    if other.tag == "Hand" then
        sparkle:Play()          -- injected ParticleSystem
        scoreManager.add(1)     -- injected LuaBehaviour on the Player
        CS.UnityEngine.Object.Destroy(self.gameObject)
    end
end

Avoid new C#. Custom C# scripts must be manually reviewed by DreamPark and only run on devices after they ship inside a future app release — expect a significantly longer path to release and slower iteration on every change afterward. Porting existing Unity content? Convert the gameplay scripts to Lua as you bring them in; most C# translates line for line. If you hit something that truly seems impossible in Lua, talk to us before writing C#.

Third-party assets

You'll bring in art packs, audio libraries, shaders, plugins, and the like from the Asset Store or external sources. Unity imports them into Assets/ThirdPartyLocal/ by default — that folder is gitignored and stripped from builds, so it's a safe staging area to experiment.

When you're actually using a third-party asset, move it into your content folder so it ships with your build. Don't shuffle files by hand — the SDK ships a tool that does it for you:

menuDreamPark → Manage Third Party Assets

This tool — Third Party Sync — scans your content folder for references, follows them to the third-party files those references point to, and moves them from ThirdPartyLocal/ into Assets/Content/<your-id>/ThirdParty/. It preserves Unity GUIDs so prefab and scene references don't break. The same sync also runs automatically as part of the Content Uploader's Compile & Upload flow, so you can let it handle the move on publish if you'd rather not think about it.

Why bother? Anything in ThirdPartyLocal/ doesn't ship in your build. Anything in your content folder's ThirdParty/ does. The sync tool draws that line cleanly.

Publishing

Publishing is one panel: DreamPark → Content Uploader. You'll use it for every release.

Fill in:

Then choose an upload mode:

Hit Compile & Upload. A progress popup shows what's happening as the panel runs optimization checks, packages your build as Unity Addressables, and pushes it to DreamPark. Your attraction goes live to venues from there.

Revenue sharing is governed by your Revenue Sharing Agreement. The economics — what counts as revenue, how the waterfall splits, when you get paid — are explained in plain English here.

Updating the SDK

When DreamPark ships a new SDK version, the editor checks for it on launch and shows a small popup with release notes. You can also check on demand:

menuDreamPark → Check for SDK Updates

The update is delivered as a .unitypackage file. When you click Update Now, the editor downloads it and opens Unity's standard import dialog so you can review what's changing (and uncheck anything you've locally modified). Click Import and you're on the new version.

You can dismiss an update and keep working — it's not blocking. Per the SDK Use Agreement, the expectation is to update within 30 days so your builds stay compatible with current venue hardware and OS.

Optimization

The SDK ships dedicated tools to slim down your build before publishing. They live under DreamPark → Optimization:

Run them before each publish. They make a meaningful difference to download size on real venue networks, and the Content Uploader will surface optimization warnings if you skip them.

Troubleshooting

The Content ID Setup popup keeps reappearing

The popup shows whenever the project doesn't have a valid content ID set. If you've already named yours and it keeps coming back, check that the content folder under Assets/Content/ still exists and the ID matches the format (starts with a letter, alphanumeric or underscore, 2–64 chars).

Login popup keeps coming back

The Content Uploader and SDK Update Checker need you to be signed in. If you keep getting bounced to the login popup, your session has likely expired — sign in once and it should hold. If it persists, check that your computer's clock is correct (session validation is time-sensitive).

"DreamPark/Troubleshooting" menu

The editor includes a built-in menu at DreamPark → Troubleshooting with one-click fixes for common issues: regenerating attraction previews, regenerating Lua codegen, cleaning addressables, fixing broken script references. Try those first.

Builds are huge

Usually traceable to unoptimized or unused assets in your content folder's ThirdParty/. Run the tools under DreamPark → Optimization to find the worst offenders, and use DreamPark → Manage Third Party Assets to make sure you're only shipping what you actually use.

Lua changes aren't picked up

If you've added a new .lua file or renamed something, Unity may need to regenerate the Lua bindings before the new script is visible. Run DreamPark → Troubleshooting → Regen Lua Codegen and Play again. For OTA pushes to live venues, the next guest session picks up the new Lua — no app rebuild needed.

Get support

The fastest place to reach us: