Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 1 addition & 2 deletions docs/pages/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Command machines, turn chests into shops and doors into toll gates. Build curren

On the following pages you'll learn about:

- [Programs](/programs): Smart contracts that define the rules of your onchain entities
- [Apps](/apps): Custom user interfaces that integrate with the native client
- [Programs](/programs): How programs work
- [Bots](/bots): How to automate tasks in DUST
- [Examples](/examples/swap-chest): Practical end-to-end use cases
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Introduction
# Custom UIs

The DUST client supports embedded apps - web apps that integrate directly into the game client UI and interact with in-game objects and physics. Apps let developers build on top of the world and extend the game client with custom functionality like shops and marketplaces.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Registration

Smart contract programs deployed to the DUST world will automatically show up in the explorer. You can also register a custom UI for your program in 3 different places:

- sidebar: a list of global apps
- spawn screen: a list of apps shown on the spawn screen
- when interacting with smart items: shown when a user interacts with a smart object with your program attached

## Preview an app in the client

Before registering an app to make it available to everyone, you can preview your app in the production client by using the `debug-app` URL parameter.
Expand Down Expand Up @@ -34,7 +40,7 @@ To make an app available in everyone's client, you have to register it in the gl

## Register a contextual app

To show a contextual app when interacting with an entity that has [your program installed](../programs/registration.md), your program needs to implement the [`appConfigURI` function](https://github.com/dustproject/dust/blob/main/packages/dustkit/contracts/IAppConfigURI.sol).
To show a contextual app when interacting with an entity that has your program installed, your program needs to implement the [`appConfigURI` function](https://github.com/dustproject/dust/blob/main/packages/dustkit/contracts/IAppConfigURI.sol).

```solidity
// SPDX-License-Identifier: MIT
Expand Down
105 changes: 10 additions & 95 deletions docs/pages/programs/index.md
Original file line number Diff line number Diff line change
@@ -1,102 +1,17 @@
Programs represent an abstraction layer that enables dynamic behavior and programmable logic for entities within DUST. Programs offer a flexible mechanism for extending entity functionality through custom logic that can respond to various in-world events.
## Programs

## Core Concepts
![program diagram](/program-diagram.png)

Programs in this architecture are defined by several key abstractions:
Programs can read from the world and influence it via smart objects.

- **ProgramId**: A unique identifier that references a specific program implementation (the underlying value is a MUD `ResourceId`)
- **EntityId**: A unique identifier for entities within the world (ForceFields, Chests, etc)
- **Program**: Smart contracts (MUD systems) which can be attached to specific entities to define their behavior
The state of the world is stored in MUD tables. You can see the full list of tables on the mud.config.

### Event-Driven Architecture
To read the tables in a smart contract, you import the table library and then pass in the keys. To read the tables in an app/script, you can call a getter or use an indexer (eg. MUD stash).

Programs follow an event-driven architecture where system contracts invoke program hooks in response to specific actions. This pattern allows for:
Programs can be attached to smart objects in the world (eg chests, force fields), and the world will call your program for certain interactions.

1. **Decoupling**: World systems and programs are loosely coupled, communicating through well-defined interfaces
2. **Extensibility**: New hooks can be added without modifying core systems
3. **Composability**: A program can be attached to different types of entities, and optionally implement the hooks related to those entity types
Smart contract programs deployed to the DUST world will automatically show up in the explorer. You can also register a custom UI for your program in 3 different places:

### ProgramId and Resource Management

The `ProgramId` type serves as the fundamental reference to program implementations. It is defined as:

```solidity
type ProgramId is bytes32;
```

Programs are registered as systems within the MUD framework, and `ProgramId`s encode the corresponding `ResourceId` of the system.

### Program Attachment and Validation

The `ProgramSystem` contract manages the attachment and detachment of programs to entities:

```solidity
function attachProgram(EntityId caller, EntityId target, ProgramId program, bytes calldata extraData) public {
// Validation logic
// ...

EntityProgram._set(target, program);

program.callOrRevert(abi.encodeCall(IAttachHook.onAttachProgram, (caller, target, extraData)));

// Notification logic
// ...
}

function detachProgram(EntityId caller, EntityId target, bytes calldata extraData) public {
// Validation logic
// ...

ProgramId program = target.getProgram();

bytes memory onDetachProgram = abi.encodeCall(IDetachProgramHook.onDetachProgram, (caller, target, extraData));

(EnergyData memory machineData, ) = updateMachineEnergy(forceField);
if (machineData.energy > 0) {
program.callOrRevert(onDetachProgram);
} else {
program.call({ gas: SAFE_PROGRAM_GAS, hook: onDetachProgram });
}

EntityProgram._deleteRecord(target);

// Notification logic
// ...
}
```

A key aspect of program attachment is the validation process. Before a program can be attached to an entity, it must pass validation checks:

1. The program must be registered as a private system
2. If the entity being programmed is within an active ForceField, the forcefield's program `validateProgram` hook must accept the attachment
3. The program itself must accept the attachment through the `onAttachProgram` hook

This multi-layered validation ensures that only appropriate programs can be attached to entities, maintaining the integrity of the world.

### Gas Safety Mechanisms

To prevent malicious or poorly implemented programs from consuming excessive gas, calls with a fixed amount of gas are used. Safe calls are only used for hooks that correspond to actions that the entity might be incentivized to prevent (e.g. `onHit`).

The `SAFE_PROGRAM_GAS` constant (set to 1,000,000 gas units) limits the gas available to safe program calls, preventing the program from consuming all the gas available in the transaction.

## Program Execution in Context

### Machine Interactions

Programs can respond to interactions with machines, such as when a player fuels a machine:

```solidity
function fuelMachine(EntityId callerEntityId, EntityId machineEntityId, uint16 fuelAmount) public {
// Validation and fuel logic
// ...

// Call program hook
ProgramId program = baseEntityId.getProgram();
program.callOrRevert(abi.encodeCall(IFuelHook.onFuel, (callerEntityId, baseEntityId, fuelAmount, "")));

// Notification logic
// ...
}
```

This allows machines to execute custom logic when they receive fuel, potentially triggering complex behaviors or state changes.
- sidebar: a list of global apps
- spawn screen: a list of apps shown on the spawn screen
- when interacting with smart items: shown when a user interacts with a smart object with your program attached
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Data Model
# Reading The World

DUST is built using [MUD](https://mud.dev/), and so the [mud.config.ts](https://github.com/dustproject/dust/blob/main/packages/world/mud.config.ts) defines all the different entities and components. Here we look at 2 specific kinds of data and how to read them.

Expand Down Expand Up @@ -95,7 +95,7 @@ SELECT "entityId", "x", "y", "z" FROM "EntityPosition" WHERE "entityId" = '0x01c

This shows the player is at `[1380, 79, -2434]`.

### Reading In A Program
### Reading In A Smart Contract

```solidity
import { EntityId, EntityTypeLib } from "@dust/world/src/types/EntityId.sol";
Expand Down Expand Up @@ -185,7 +185,7 @@ SELECT "owner", "slot", "entityId", "objectType", "amount" FROM "InventorySlot"

This shows all the items the player has. eg, the player has 4 WheatSeeds (id 134) in slot 2.

### Reading In A Program
### Reading In A Smart Contract

```solidity
import { InventorySlot, InventorySlotData } from "@dust/world/src/codegen/tables/InventorySlot.sol";
Expand Down
96 changes: 96 additions & 0 deletions docs/pages/programs/smart-objects/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Smart Objects

Programs can be attached to smart objects in the world (eg chests, force fields), and the world will call your program for certain interactions.

## Core Concepts

Programs in this architecture are defined by several key abstractions:

- **ProgramId**: A unique identifier that references a specific program implementation (the underlying value is a MUD `ResourceId`)
- **EntityId**: A unique identifier for entities within the world (ForceFields, Chests, etc)
- **Program**: Smart contracts (MUD systems) which can be attached to specific entities to define their behavior

### ProgramId and Resource Management

The `ProgramId` type serves as the fundamental reference to program implementations. It is defined as:

```solidity
type ProgramId is bytes32;
```

Programs are registered as systems within the MUD framework, and `ProgramId`s encode the corresponding `ResourceId` of the system.

### Program Attachment and Validation

The `ProgramSystem` contract manages the attachment and detachment of programs to entities:

```solidity
function attachProgram(EntityId caller, EntityId target, ProgramId program, bytes calldata extraData) public {
// Validation logic
// ...

EntityProgram._set(target, program);

program.callOrRevert(abi.encodeCall(IAttachHook.onAttachProgram, (caller, target, extraData)));

// Notification logic
// ...
}

function detachProgram(EntityId caller, EntityId target, bytes calldata extraData) public {
// Validation logic
// ...

ProgramId program = target.getProgram();

bytes memory onDetachProgram = abi.encodeCall(IDetachProgramHook.onDetachProgram, (caller, target, extraData));

(EnergyData memory machineData, ) = updateMachineEnergy(forceField);
if (machineData.energy > 0) {
program.callOrRevert(onDetachProgram);
} else {
program.call({ gas: SAFE_PROGRAM_GAS, hook: onDetachProgram });
}

EntityProgram._deleteRecord(target);

// Notification logic
// ...
}
```

A key aspect of program attachment is the validation process. Before a program can be attached to an entity, it must pass validation checks:

1. The program must be registered as a private system
2. If the entity being programmed is within an active ForceField, the forcefield's program `validateProgram` hook must accept the attachment
3. The program itself must accept the attachment through the `onAttachProgram` hook

This multi-layered validation ensures that only appropriate programs can be attached to entities, maintaining the integrity of the world.

### Gas Safety Mechanisms

To prevent malicious or poorly implemented programs from consuming excessive gas, calls with a fixed amount of gas are used. Safe calls are only used for hooks that correspond to actions that the entity might be incentivized to prevent (e.g. `onHit`).

The `SAFE_PROGRAM_GAS` constant (set to 1,000,000 gas units) limits the gas available to safe program calls, preventing the program from consuming all the gas available in the transaction.

## Program Execution in Context

### Machine Interactions

Programs can respond to interactions with machines, such as when a player fuels a machine:

```solidity
function fuelMachine(EntityId callerEntityId, EntityId machineEntityId, uint16 fuelAmount) public {
// Validation and fuel logic
// ...

// Call program hook
ProgramId program = baseEntityId.getProgram();
program.callOrRevert(abi.encodeCall(IFuelHook.onFuel, (callerEntityId, baseEntityId, fuelAmount, "")));

// Notification logic
// ...
}
```

This allows machines to execute custom logic when they receive fuel, potentially triggering complex behaviors or state changes.
Binary file added docs/public/program-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 26 additions & 15 deletions docs/vocs.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,36 @@ export default defineConfig({
sidebar: [
{
text: "Overview",
items: [
{ text: "Introduction", link: "/" },
{ text: "Data Model", link: "/data-model" },
],
items: [{ text: "Introduction", link: "/" }],
},
{
text: "Programs (contracts)",
text: "Programs",
items: [
{ text: "Introduction", link: "/programs" },
{ text: "Registration", link: "/programs/registration" },
{ text: "Reference", link: "/programs/reference" },
],
},
{
text: "Apps (client)",
items: [
{ text: "Introduction", link: "/apps" },
{ text: "Registration", link: "/apps/registration" },
{ text: "DustKit", link: "/apps/dustkit" },
{ text: "Reading The World", link: "/programs/reading-the-world" },
{
text: "Smart Objects",
link: "/programs/smart-objects",
collapsed: false,
items: [
{ text: "Overview", link: "/programs/smart-objects" },
{
text: "Registration",
link: "/programs/smart-objects/registration",
},
{ text: "Reference", link: "/programs/smart-objects/reference" },
],
},
{
text: "Custom UIs",
link: "/programs/custom-uis",
collapsed: false,
items: [
{ text: "Overview", link: "/programs/custom-uis" },
{ text: "Dustkit", link: "/programs/custom-uis/dustkit" },
{ text: "Registration", link: "/programs/custom-uis/registration" },
],
},
],
},
{
Expand Down