diff --git a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md
index a4d743813d1..06e30fb7b2a 100644
--- a/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md
+++ b/docs/docs/00200-core-concepts/00200-functions/00300-reducers/00400-reducer-context.md
@@ -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:
+
+
+
+
+```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));
+```
+
+
+
+
+```csharp
+double fraction = ctx.Rng.NextDouble(); // [0.0, 1.0)
+int roll = ctx.Rng.Next(1, 7); // [1, 7)
+```
+
+
+
+
+```rust
+use spacetimedb::rand::Rng;
+
+let value: u32 = ctx.random();
+let roll: u32 = ctx.rng().gen_range(1..=6);
+```
+
+
+
+
+```cpp
+auto& rng = ctx.rng();
+int32_t roll = rng.gen_range(1, 6); // inclusive
+```
+
+
+
+
## 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.
diff --git a/docs/docs/00200-core-concepts/00600-clients/00200-codegen.md b/docs/docs/00200-core-concepts/00600-clients/00200-codegen.md
index f648e17a578..3575377a20a 100644
--- a/docs/docs/00200-core-concepts/00600-clients/00200-codegen.md
+++ b/docs/docs/00200-core-concepts/00600-clients/00200-codegen.md
@@ -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}`);
});
```
diff --git a/docs/docs/00200-core-concepts/00600-clients/00300-connection.md b/docs/docs/00200-core-concepts/00600-clients/00300-connection.md
index 8882aa3c80d..f1ad4c73d42 100644
--- a/docs/docs/00200-core-concepts/00600-clients/00300-connection.md
+++ b/docs/docs/00200-core-concepts/00600-clients/00300-connection.md
@@ -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();
```
@@ -80,9 +81,10 @@ To connect to a database hosted on MainCloud:
```typescript
-const conn = new DbConnection.builder()
+const conn = DbConnection.builder()
.withUri("https://maincloud.spacetimedb.com")
- .withDatabaseName("my_database");
+ .withDatabaseName("my_database")
+ .build();
```
@@ -126,10 +128,11 @@ To authenticate with a token (for example, from [SpacetimeAuth](../00500-authent
```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();
```
diff --git a/docs/docs/00200-core-concepts/00600-clients/00700-typescript-reference.md b/docs/docs/00200-core-concepts/00600-clients/00700-typescript-reference.md
index 759a0f85f10..66abdda2021 100644
--- a/docs/docs/00200-core-concepts/00600-clients/00700-typescript-reference.md
+++ b/docs/docs/00200-core-concepts/00600-clients/00700-typescript-reference.md
@@ -1088,7 +1088,7 @@ function MyComponent() {
return (
Connected as: {identity?.toHexString()}
-
@@ -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.
diff --git a/skills/concepts/SKILL.md b/skills/concepts/SKILL.md
index 402a1a8ff18..9c4195fc1bd 100644
--- a/skills/concepts/SKILL.md
+++ b/skills/concepts/SKILL.md
@@ -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.