home / skills / dojoengine / book / dojo-client
This skill helps you connect and bind your game clients to a Dojo world, generating bindings and enabling real-time queries.
npx playbooks add skill dojoengine/book --skill dojo-clientReview the files below or copy the command above to add this skill to your agents.
---
name: dojo-client
description: 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.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---
# Dojo Client Integration
Connect your game client or frontend to your deployed Dojo world across multiple platforms.
## When to Use This Skill
- "Set up JavaScript SDK for my Dojo game"
- "Integrate Dojo with Unity"
- "Generate TypeScript bindings"
- "Connect React app to my world"
## What This Skill Does
Handles client integration for:
- JavaScript/TypeScript SDK (primary)
- Unity, Unreal, Godot, Bevy (game engines)
- Typed binding generation
- Query/subscription patterns
## Supported Platforms
| Platform | Language | Package |
|----------|----------|---------|
| JavaScript/TypeScript | JS/TS | `@dojoengine/sdk` |
| Unity | C# | `dojo.unity` |
| Unreal Engine | C++ | `dojo.unreal` |
| Godot | GDScript | `dojo.godot` |
| Bevy | Rust | `dojo.bevy` |
| C/C++ | C/C++ | `dojo.c` |
## JavaScript/TypeScript Integration
### Quick Start
Use the quickstart wizard:
```bash
pnpx @dojoengine/create-dojo start
```
### Manual Setup
1. **Install dependencies:**
```bash
# Essential packages
pnpm add @dojoengine/core @dojoengine/sdk @dojoengine/torii-client
# For React integration
pnpm add @dojoengine/create-burner @dojoengine/utils
# For state management
pnpm add @dojoengine/state zustand immer
# Build tools for WASM support
pnpm add -D vite-plugin-wasm vite-plugin-top-level-await
```
2. **Create `dojoConfig.ts`:**
```typescript
import { createDojoConfig } from "@dojoengine/core";
import manifest from "../path/to/manifest_dev.json";
export const dojoConfig = createDojoConfig({ manifest });
```
3. **Generate TypeScript bindings:**
```bash
DOJO_MANIFEST_PATH="../path/to/Scarb.toml" sozo build --typescript
```
4. **Initialize the SDK:**
```typescript
import { init } from "@dojoengine/sdk";
import { DojoSdkProvider } from "@dojoengine/sdk/react";
import { dojoConfig } from "./dojoConfig.ts";
import { setupWorld } from "./bindings/typescript/contracts.gen.ts";
import type { SchemaType } from "./bindings/typescript/models.gen.ts";
async function main() {
const sdk = await init<SchemaType>({
client: {
worldAddress: dojoConfig.manifest.world.address,
toriiUrl: "http://localhost:8080",
relayUrl: "/ip4/127.0.0.1/tcp/9090",
},
domain: {
name: "MyDojoProject",
version: "1.0",
chainId: "KATANA",
revision: "1",
},
});
// Use in React
createRoot(document.getElementById("root")!).render(
<DojoSdkProvider sdk={sdk} dojoConfig={dojoConfig} clientFn={setupWorld}>
<App />
</DojoSdkProvider>
);
}
```
### Querying Entities
```typescript
import { ToriiQueryBuilder, KeysClause, MemberClause } from "@dojoengine/sdk";
// Simple query: Find a specific player
const entities = await sdk.getEntities({
query: new ToriiQueryBuilder().withClause(
KeysClause(["dojo_starter-Player"], ["0xabcde..."], "FixedLen").build()
),
});
// Access the results
entities.items.forEach((entity) => {
const player = entity.models.dojo_starter.Player;
console.log(`Player: ${player?.name}, Score: ${player?.score}`);
});
```
### Complex Queries
```typescript
const entities = await sdk.getEntities({
query: new ToriiQueryBuilder()
.withClause(
MemberClause("dojo_starter-Player", "score", "Gt", 0).build()
)
.withLimit(10)
.withOffset(0)
.withOrderBy([{ field: "score", direction: "Desc" }]),
});
```
### Subscribing to Changes
```typescript
const [initialEntities, subscription] = await sdk.subscribeEntityQuery({
query: new ToriiQueryBuilder()
.withClause(
MemberClause("dojo_starter-Player", "score", "Gt", 100).build()
)
.includeHashedKeys(),
callback: ({ data, error }) => {
if (data) {
data.forEach((entity) => {
const player = entity.models.dojo_starter.Player;
console.log(`Player ${player?.id}: ${player?.score} points`);
});
}
},
});
// Cancel later
// subscription.cancel();
```
### React Hooks
```typescript
import { useEntityQuery, useModels, useModel, useEntityId } from "@dojoengine/sdk/react";
function MyComponent() {
// Subscribe to entity changes
useEntityQuery(
new ToriiQueryBuilder()
.withClause(MemberClause("dojo_starter-Item", "durability", "Eq", 2).build())
.includeHashedKeys()
);
// Get all items from the store
const items = useModels("dojo_starter-Item");
// Get a single item by entity ID
const entityId = useEntityId(1);
const item = useModel(entityId, "dojo_starter-Item");
return (
<div>
{Object.entries(items).map(([id, item]) => (
<div key={id}>Item {id}: durability {item?.durability}</div>
))}
</div>
);
}
```
### Executing Systems
```typescript
import { useDojoSDK } from "@dojoengine/sdk/react";
import { useAccount } from "@starknet-react/core";
function GameActions() {
const { client } = useDojoSDK();
const { account } = useAccount();
async function spawn() {
await client.actions.spawn({ account });
}
async function move(direction: number) {
await client.actions.move({ account, direction });
}
return (
<div>
<button onClick={spawn}>Spawn</button>
<button onClick={() => move(1)}>Move Right</button>
</div>
);
}
```
## Game Engine Integration
### Unity
See [dojo.unity documentation](https://github.com/dojoengine/dojo.unity) for:
- Package installation via Unity Package Manager
- C# bindings generation
- Entity synchronization patterns
- Transaction handling
### Unreal Engine
See [dojo.unreal documentation](https://github.com/dojoengine/dojo.unreal) for:
- Plugin installation
- Blueprint integration
- C++ SDK usage
### Godot
See [dojo.godot documentation](https://github.com/dojoengine/dojo.godot) for:
- GDScript integration
- Signal-based subscriptions
## Client Integration Checklist
### Pre-Integration
- [ ] World deployed (`dojo-deploy` skill)
- [ ] Torii indexer running (`dojo-indexer` skill)
- [ ] World address recorded
- [ ] RPC endpoint accessible
### Setup
- [ ] SDK/package installed
- [ ] Bindings generated (`sozo build --typescript`)
- [ ] Manifest imported
- [ ] SDK initialized
- [ ] Test queries work
### Integration
- [ ] Entity reads working
- [ ] System executions working
- [ ] Subscriptions configured
- [ ] Error handling added
## Troubleshooting
### "Cannot connect to RPC"
- Verify RPC URL is correct
- Check Katana/Torii is running
- Verify network is reachable
### "World not found"
- Check world address is correct
- Verify world is deployed
- Check RPC is pointing to correct network
### "Model not found"
- Ensure model is deployed
- Check model name includes namespace (`dojo_starter-Position`)
- Verify entity exists with that key
## Next Steps
After client integration:
1. Test end-to-end workflow
2. Implement optimistic updates
3. Add error handling
4. Connect wallet for transactions
## Related Skills
- **dojo-deploy**: Deploy world first
- **dojo-indexer**: Set up Torii for queries
- **dojo-world**: Configure permissions
- **dojo-migrate**: Update client after migrations
This skill integrates Dojo with game clients and frontends across JavaScript, Unity, Unreal, Godot, Bevy, and native platforms. It generates typed bindings, initializes SDK clients, and provides query, subscription, and system execution helpers so your client talks to a deployed Dojo world reliably. Use it to wire UI, engines, and gameplay code to your world manifest and indexer.
The skill generates platform-specific bindings (TypeScript, C#, C++, GDScript, Rust, C/C++) from your Dojo manifest and creates connection scaffolding for the Dojo SDK. It initializes an SDK client pointing at your world address, Torii indexer, and RPC/relay endpoints, then exposes query builders, subscription callbacks, and action APIs for executing systems. For web apps it also provides React providers and hooks to subscribe to entity state and run systems from components.
What do I need running before integrating a client?
A deployed Dojo world, a running Torii indexer, and an accessible RPC/relay endpoint. Record the world address and confirm network connectivity.
How do I update client bindings after changing the manifest?
Regenerate bindings (e.g., sozo build --typescript or engine-specific generator), replace the generated files in your client, and rebuild the client to pick up schema changes.