Integrate Dojo with game clients for JavaScript, Unity, Unreal, Rust, and other platforms. Generate typed bindings and connection code. Use when connecting frontends or game engines to your Dojo world.
Generate typed client bindings and connection code for Dojo worlds across JavaScript, Unity, Unreal, Rust, and other platforms. Use when connecting frontends or game engines to deployed Dojo worlds.
/plugin marketplace add dojoengine/book/plugin install book@dojoengineThis skill is limited to using the following tools:
Connect your game client or frontend to your deployed Dojo world across multiple platforms.
Handles client integration for:
JavaScript:
"Set up the Dojo JavaScript SDK"
Unity:
"Integrate my Dojo world with Unity"
Unreal:
"Connect Unreal Engine to my deployed world"
| Platform | Language | Package |
|---|---|---|
| JavaScript/TypeScript | JS/TS | @dojoengine/sdk |
| Unity | C# | dojo.unity |
| Unreal Engine | C++ | dojo.unreal |
| Rust | Rust | dojo::client |
| Godot | GDScript | dojo.godot |
| Bevy | Rust | dojo.bevy |
| C/C++ | C/C++ | dojo.c |
npm install @dojoengine/sdk
# or
pnpm add @dojoengine/sdk
sozo build --typescript-output ./src/generated
import { DojoProvider } from "@dojoengine/sdk";
import manifest from "./manifest.json";
// Create provider
const provider = new DojoProvider(
manifest,
"http://localhost:5050" // Katana RPC
);
// Read a model
const position = await provider.getEntity("Position", playerId);
console.log(position.x, position.y);
// Execute a system
await provider.execute("actions", "spawn", []);
// Get single entity
const player = await provider.getEntity("Player", address);
// Get multiple entities
const positions = await provider.getEntities("Position");
// Query with filters
const positions = await provider.query("Position", {
where: { x: { $gt: 10 } }
});
// Subscribe to entity changes
const unsubscribe = provider.subscribe(
"Position",
playerId,
(position) => {
console.log("Position updated:", position);
}
);
// Unsubscribe later
unsubscribe();
import { Account } from "starknet";
// Create account
const account = new Account(
provider.provider,
accountAddress,
privateKey
);
// Execute with account
await provider.execute(
"actions",
"move",
[Direction.Up],
{ account }
);
Add to manifest.json:
{
"dependencies": {
"com.dojoengine.sdk": "https://github.com/dojoengine/dojo.unity.git"
}
}
sozo build --unity-output ./Assets/Generated
using Dojo;
using Dojo.Starknet;
public class DojoManager : MonoBehaviour
{
private DojoConnection connection;
async void Start()
{
// Connect to world
connection = new DojoConnection(
"http://localhost:5050",
worldAddress
);
await connection.Connect();
// Read model
var position = await connection.GetEntity<Position>(playerId);
Debug.Log($"Position: {position.x}, {position.y}");
// Execute system
await connection.Execute("actions", "spawn");
}
}
public class PlayerController : MonoBehaviour
{
private Position position;
async void Start()
{
// Subscribe to position updates
await connection.Subscribe<Position>(playerId, OnPositionUpdate);
}
void OnPositionUpdate(Position newPosition)
{
position = newPosition;
transform.position = new Vector3(position.x, 0, position.y);
}
public async void Move(Direction direction)
{
await connection.Execute("actions", "move", direction);
}
}
dojo.unreal pluginPlugins/ foldersozo build --cpp-output ./Source/MyGame/Generated
#include "DojoClient.h"
void AGameMode::BeginPlay()
{
Super::BeginPlay();
// Create client
DojoClient = NewObject<UDojoClient>();
DojoClient->Initialize(
TEXT("http://localhost:5050"),
WorldAddress
);
// Read model
FPosition Position = DojoClient->GetEntity<FPosition>(PlayerId);
UE_LOG(LogTemp, Log, TEXT("Position: %d, %d"), Position.X, Position.Y);
// Execute system
DojoClient->Execute(TEXT("actions"), TEXT("spawn"));
}
UCLASS(BlueprintType)
class UDojoFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, Category = "Dojo")
static void ExecuteSpawn(UDojoClient* Client)
{
Client->Execute(TEXT("actions"), TEXT("spawn"));
}
UFUNCTION(BlueprintCallable, Category = "Dojo")
static FPosition GetPlayerPosition(UDojoClient* Client, FString PlayerId)
{
return Client->GetEntity<FPosition>(PlayerId);
}
};
[dependencies]
dojo-client = { git = "https://github.com/dojoengine/dojo" }
tokio = { version = "1", features = ["full"] }
use dojo_client::{DojoClient, WorldReader};
#[tokio::main]
async fn main() {
// Create client
let client = DojoClient::new(
"http://localhost:5050",
world_address
).await.unwrap();
// Read model
let position: Position = client
.read_model(player_id)
.await
.unwrap();
println!("Position: {}, {}", position.x, position.y);
// Execute system
client
.execute("actions", "spawn", vec![])
.await
.unwrap();
}
// Get world address from manifest
import manifest from "./manifest.json";
const worldAddress = manifest.world.address;
// Create provider
const provider = new DojoProvider(manifest, rpcUrl);
Polling (simple):
setInterval(async () => {
const position = await provider.getEntity("Position", playerId);
updateUI(position);
}, 1000);
Subscriptions (efficient):
provider.subscribe("Position", playerId, (position) => {
updateUI(position);
});
try {
// Execute transaction
const tx = await provider.execute("actions", "move", [Direction.Up]);
// Wait for confirmation
await provider.waitForTransaction(tx.transaction_hash);
// Update UI
console.log("Move successful!");
} catch (error) {
console.error("Move failed:", error);
}
// Execute multiple actions
const txs = await Promise.all([
provider.execute("actions", "move", [Direction.Up]),
provider.execute("actions", "attack", [targetId]),
provider.execute("actions", "heal", []),
]);
// Wait for all
await Promise.all(
txs.map(tx => provider.waitForTransaction(tx.transaction_hash))
);
dojo-deploy skill)dojo-indexer skill)sozo build --<platform>-output)After client integration:
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.