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
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,46 @@ The context provides access to a random number generator that is deterministic a
Never use external random number generators (like `Random` in C# without using the context). These are non-deterministic and will cause different nodes to produce different results, breaking consensus.
:::

Use the context-provided random API for any reducer logic that needs random values:

<Tabs groupId="server-language" queryString>
<TabItem value="typescript" label="TypeScript">

```typescript
const fraction = ctx.random(); // [0.0, 1.0)
const roll = ctx.random.integerInRange(1, 6); // inclusive
const bytes = ctx.random.fill(new Uint8Array(16));
```

</TabItem>
<TabItem value="csharp" label="C#">

```csharp
double fraction = ctx.Rng.NextDouble(); // [0.0, 1.0)
int roll = ctx.Rng.Next(1, 7); // [1, 7)
```

</TabItem>
<TabItem value="rust" label="Rust">

```rust
use spacetimedb::rand::Rng;

let value: u32 = ctx.random();
let roll: u32 = ctx.rng().gen_range(1..=6);
```

</TabItem>
<TabItem value="cpp" label="C++">

```cpp
auto& rng = ctx.rng();
int32_t roll = rng.gen_range(1, 6); // inclusive
```

</TabItem>
</Tabs>

## Module Identity

The context provides access to the module's own identity, which is useful when a reducer needs to refer to the database itself.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/00200-core-concepts/00600-clients/00200-codegen.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ For example, a `create_user` reducer becomes:

```typescript
// Call the reducer
conn.reducers.createUser(name, email);
conn.reducers.createUser({ name, email });

// Register a callback to observe reducer invocations
conn.reducers.onCreateUser((ctx, name, email) => {
conn.reducers.onCreateUser((ctx, { name, email }) => {
console.log(`User created: ${name}`);
});
```
Expand Down
15 changes: 9 additions & 6 deletions docs/docs/00200-core-concepts/00600-clients/00300-connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ Create a connection using the `DbConnection` builder pattern:
```typescript
import { DbConnection } from './module_bindings';

const conn = new DbConnection.builder()
const conn = DbConnection.builder()
.withUri("https://maincloud.spacetimedb.com")
.withDatabaseName("my_database");
.withDatabaseName("my_database")
.build();
```

</TabItem>
Expand Down Expand Up @@ -80,9 +81,10 @@ To connect to a database hosted on MainCloud:
<TabItem value="typescript" label="TypeScript">

```typescript
const conn = new DbConnection.builder()
const conn = DbConnection.builder()
.withUri("https://maincloud.spacetimedb.com")
.withDatabaseName("my_database");
.withDatabaseName("my_database")
.build();
```

</TabItem>
Expand Down Expand Up @@ -126,10 +128,11 @@ To authenticate with a token (for example, from [SpacetimeAuth](../00500-authent
<TabItem value="typescript" label="TypeScript">

```typescript
const conn = new DbConnection.builder()
const conn = DbConnection.builder()
.withUri("https://maincloud.spacetimedb.com")
.withDatabaseName("my_database")
.withToken("your_auth_token_here");
.withToken("your_auth_token_here")
.build();
```

</TabItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ function MyComponent() {
return (
<div>
<p>Connected as: {identity?.toHexString()}</p>
<button onClick={() => conn?.reducers.createPlayer('Alice')}>
<button onClick={() => conn?.reducers.createPlayer({ name: 'Alice' })}>
Create Player
</button>
</div>
Expand Down Expand Up @@ -1136,7 +1136,7 @@ import { useReducer } from 'spacetimedb/react';
import { reducers } from './module_bindings';

const createPlayer = useReducer(reducers.createPlayer);
createPlayer('Alice');
createPlayer({ name: 'Alice' });
```

`useReducer` returns a function that calls the generated reducer. Calls made before the connection is ready are queued and flushed once the connection is established.
Expand Down
2 changes: 1 addition & 1 deletion skills/concepts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ SpacetimeDB is a relational database that is also a server. It lets you upload a
## Critical Rules

1. **Reducers are transactional.** They do not return data to callers. Use subscriptions to read data.
2. **Reducers must be deterministic.** No filesystem, network, timers, or random. All state must come from tables.
2. **Reducers must be deterministic.** Do not use filesystem, network, external clocks, or external random sources in reducers. Use `ReducerContext` for SpacetimeDB-provided timestamp and deterministic random values.
3. **Read data via tables/subscriptions**, not reducer return values. Clients get data through subscribed queries.
4. **Auto-increment IDs are not sequential.** Gaps are normal, do not use for ordering. Use timestamps or explicit sequence columns.
5. **`ctx.sender` is the authenticated principal.** Never trust identity passed as arguments.
Expand Down
Loading