create-scene について
Decentraland SDK7の新規シーン作成を、要件確認から`/init`による土台作成、アセット選定、ファイル設定まで案内するスキルです。宣言的なエンティティと動作の分離を重視し、シーン制作者を支援します。
主な機能
- 01シーン要件の確認
- 02`/init`によるプロジェクト作成
- 033Dモデルと音声カタログの検索
- 04シーンファイルと区画の設定
- 05宣言的なエンティティと動作の分離
活用シーン
- 01ギャラリー、ゲーム、交流シーンの開始
- 02テーマに合うモデルや音声の選定
- 03スポーン地点と区画配置の設定
- 04新規シーンのプレビュー
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dcl-regenesislabs/ opendcl --skill create-sceneインストール後、Claude Code で/create-sceneを入力して読み込まれたか確認します。
詳細
新しい Decentraland SDK7 シーンを作成する
ランタイムの制約: Decentraland は QuickJS サンドボックスで実行されます。Node.js API(
fs、http、path、process)は使用できません。非同期処理には SDK のexecuteTask()とfetch()を使用してください。詳しくは scene-runtime スキルを参照してください。
ユーザーが新しいシーンの作成を希望する場合は、以下の手順に従ってください。
1. 作成するものを尋ねる
ユーザーがシーンの内容を説明していない場合は、次の点を尋ねてください。
- どのようなシーンですか?(ギャラリー、ゲーム、ソーシャルスペース、インタラクティブアートなど)
- 区画はいくつですか?(デフォルト:1 区画 = 16x16m)
- 特定の機能はありますか?(3D モデル、インタラクティブ機能、UI、マルチプレイヤー)
2. /init でプロジェクトのひな形を作成する
必ず最初に /init を実行してください。 公式の @dcl/sdk-commands init を使用して、適切かつ最新の設定で scene.json、package.json、tsconfig.json、src/index.ts を作成し、依存関係も自動的にインストールします。
scene.json、package.json、tsconfig.json を手動で作成しないでください。SDK のテンプレートはバージョン間で変更される可能性があり、手書きのファイルは実際の設定と異なるものになります。
3. 一致する 3D アセットを探す
シーンコードを書く前に、アセットカタログを検索して、ユーザーのテーマに合う無料モデルを探してください。
- モデルカタログを検索します(キャラクター、建造物、小道具、自然、乗り物など、最適化済みの 3D モデルが 5,700 点以上あります)。
grep -i "keyword" {baseDir}/../add-3d-models/references/model-catalog.md {baseDir}/../../context/audio-catalog.mdを読み込みます(音楽、環境音、効果音、ゲームの仕組みなど、無料サウンドが 50 点あります)。- 各カタログ行の末尾にある
preview:URL から プレビューサムネイル を取得し、モデルを目で確認します。 - 一致するモデルとサウンドをユーザーに提案します。
- 選択したモデルをシーンの
models/ディレクトリにダウンロードします。mkdir -p models curl -o models/zombie-purple.glb "https://models.dclregenesislabs.xyz/blobs/bafybeiffc..."
重要:
GltfContainerはローカルファイルでのみ動作します。モデルのsrcフィールドに外部 URL を使用しないでください。
4. 生成されたファイルをカスタマイズする
/init の完了後、ユーザーの希望に応じて生成されたファイルをカスタマイズしてください。
scene.json
display フィールドと区画を更新します。
display.title— シーン名を設定しますdisplay.description— 短い説明を設定しますscene.parcels— 複数区画のシーンの場合は、すべての区画を列挙します(例:2x2 の場合は["0,0", "0,1", "1,0", "1,1"])scene.base— 南西の角にある区画を設定します
main-entities.ts + src/index.ts
OpenDCL シーンでは、2 ファイルで構成するオーサリングモデルを使用します。
main-entities.ts(シーンのルート)— 型付きの宣言的エンティティとそのデータコンポーネントを、Name をキーとして定義します。ビルド時にmain.crdtにコンパイルされ、main()の実行前にエンジンによって事前読み込みされます。src/index.ts— 振る舞いのみを記述します。engine.getEntityOrNullByName<EntityName>(name)を使って Name でエンティティを参照し、システム、ポインターイベント、トゥイーンなどをアタッチします。
main-entities.ts の例:
import type { Scene } from '@dcl/sdk/scene-types'
export const scene = {
blue_cube: {
components: {
Transform: { position: { x: 8, y: 1, z: 8 }, rotation: { x: 0, y: 0, z: 0, w: 1 }, scale: { x: 1, y: 1, z: 1 } },
MeshRenderer: { mesh: { $case: 'box', box: { uvs: [] } } },
Material: {
material: { $case: 'pbr', pbr: { albedoColor: { r: 0.2, g: 0.5, b: 1, a: 1 } } },
},
},
},
} satisfies Scene
satisfies Scene 節を使うと、リテラルのキーを型付きのまま保持し(そのため keyof typeof scene で型付きのエンティティ名のユニオン型を取得できます)、同時に Scene スキーマに対する形状の検証も行えます。
src/index.ts の例:
import { engine, pointerEventsSystem, InputAction } from '@dcl/sdk/ecs'
import type { scene } from '../main-entities'
type EntityName = keyof typeof scene
export function main() {
const cube = engine.getEntityOrNullByName<EntityName>('blue_cube')
if (cube === null) return
pointerEventsSystem.onPointerDown(
{ entity: cube, opts: { button: InputAction.IA_POINTER, hoverText: 'Click me' } },
() => console.log('clicked'),
)
}
tsconfig.json に main-entities.ts を含めて、型チェックの対象にする必要があります。
{
"extends": "@dcl/sdk/types/tsconfig.ecs7.json",
"include": ["src/**/*.ts", "src/**/*.tsx", "main-entities.ts"]
}
ルール:
- 編集可能または宣言されたすべてのエンティティには、
main-entities.ts内で一意の Name を付ける必要があります。 - 実行時に作成される動的エンティティ(エフェクト、投射物、動的な UI マーカー)には、
engine.addEntity()を直接使用します。動的エンティティには Name を付けないでください。main-entities.tsには追加しません。 - 純粋なデータ(Transform、GltfContainer、MeshRenderer、MeshCollider、Material、AudioSource、VideoPlayer、TextShape、Animator の設定、NftShape、Billboard、VisibilityComponent)はすべて
main-entities.tsに記述します。 - 振る舞い(ポインターコールバック、システム、トゥイーンのトリガー、条件ロジック)はすべて
src/に記述します。 sceneリテラルは JSON 互換でなければなりません。オブジェクト内で関数呼び出し、スプレッド構文、コメントを使用しないでください。
scene.json リファレンス
scene.json の有効なフィールドは以下のとおりです。
| フィールド | 必須 | 説明 |
|---|---|---|
ecs7 | はい | SDK7 の場合は true にする必要があります |
runtimeVersion | はい | "7" にする必要があります |
main | はい | "bin/index.js" にする必要があります — コンパイル後の出力パスです |
display.title | 推奨 | マップと Places に表示されるシーン名 |
display.description | 推奨 | 見つけやすくするための短い説明 |
display.navmapThumbnail | 任意 | Genesis City のミニマップ用画像パス |
scene.parcels | はい | "x,y" 座標文字列の配列 |
scene.base | はい | 原点となる区画(通常は南西の角) |
spawnPoints | 任意 | プレイヤーが入場時に出現する場所(以下を参照) |
requiredPermissions | 任意 | 権限の配列(例:"ALLOW_MEDIA_HOSTNAMES") |
allowedMediaHostnames | 任意 | 外部メディア用の許可リストに登録されたドメイン |
featureToggles | 任意 | SDK の機能を有効/無効にします |
worldConfiguration | 任意 | Worlds へのデプロイ用(deploy-worlds スキルを参照) |
authoritativeMultiplayer | 任意 | 権威サーバーモードを有効にします(authoritative-server スキルを参照) |
スポーンポイント
プレイヤーがシーンに入る場所と方法を設定します。
{
"spawnPoints": [
{
"name": "spawn1",
"default": true,
"position": { "x": [1, 5], "y": [0, 0], "z": [2, 4] },
"cameraTarget": { "x": 8, "y": 1, "z": 8 }
}
]
}
- 位置の範囲(例:
[1, 5])を指定すると、プレイヤーは範囲内にランダムにスポーンします cameraTargetはスポーン時のプレイヤーのカメラの向きを設定します — シーンの中心となるエリアに向けてください- 固定スポーン:範囲ではなく単一の値を使用します(例:
"x": 8)
複数区画のレイアウト
| レイアウト | 区画の配列 | 用途 |
|---|---|---|
| 単一 | ["0,0"] | 小規模なゲーム、ギャラリー、単一ルームの体験 |
| ストリップ | ["0,0", "1,0", "2,0"] | 廊下、レーストラック、直線的な道のり |
| L 字型 | ["0,0", "1,0", "0,1"] | 角地の建物、分割された体験 |
| 2x2 正方形 | ["0,0", "1,0", "0,1", "1,1"] | 開放的な広場、アリーナ、中規模のゲーム |
| 3x3 正方形 | "0,0" から "2,2" までの 9 区画 | 大規模なゲーム、複数ルームの建物 |
基準区画: 常に scene.base を南西(x、y が最小)の角にある区画に設定します。
区画ごとの境界: 16m x 16m、高さ 20m です。2x2 のシーンは 32m x 32m の広さになります。
5. 作成後の手順
ファイルをカスタマイズしたら、次の手順を実行します。
previewツールを使用してプレビューサーバーを起動します(またはnpx @dcl/sdk-commands start --bevy-webを手動で実行します)- シーンがブラウザーの http://localhost:8000 で開きます
関連項目
- デプロイする準備はできましたか? deploy-scene スキル(Genesis City)または deploy-worlds スキル(個人用 Worlds)を参照してください
- 区画数の上限に合わせて最適化する必要がありますか? optimize-scene スキルを参照してください
- ゲームを計画していますか? 設計パターンとパフォーマンス予算については game-design スキルを参照してください
重要な注意事項
- オブジェクトは必ずシーンの境界内に配置してください(X は 0 から 16parcelsX、Z は 0 から 16parcelsZ)
- 単一区画のシーンの中心は、地面の高さで (8, 0, 8) です
- Y 軸は上向きで、最小 Y=0(地面)です
- scene.json の
mainフィールドは必ず"bin/index.js"にしてください — これはコンパイル後の出力パスです jsxとjsxImportSourceの tsconfig 設定は/initによってすでに追加されています — 変更しないでください- Transform フィールド(position、rotation、scale)に
undefined値を渡さないでください — SDK シリアライザーがクラッシュします。フィールドが任意の場合は、undefined値を含めるのではなく、キー自体を省略してください。