Skip to content
Merged
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
40 changes: 2 additions & 38 deletions creator-onboarding/artists/1-building-your-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,43 +56,7 @@ const invocation = parseInt(tokenData.tokenId) % 1_000_000

**Never use `Math.random()` or `Date.now()` as a randomness source.** These are non-deterministic — the same token would produce different outputs on different loads, which breaks the fundamental guarantee of generative art on Art Blocks.

Instead, seed a pseudo-random number generator (PRNG) from `tokenData.hash`. The recommended implementation is the **sfc32** algorithm:

```javascript
// Seeded PRNG from tokenData.hash
function sfc32(a, b, c, d) {
return function () {
a |= 0; b |= 0; c |= 0; d |= 0;
let t = (((a + b) | 0) + d) | 0;
d = (d + 1) | 0;
a = b ^ (b >>> 9);
b = (c + (c << 3)) | 0;
c = (c << 21) | (c >>> 11);
c = (c + t) | 0;
return (t >>> 0) / 4294967296;
};
}

function hashToSeeds(hash) {
const hex = hash.slice(2); // remove "0x"
return [
parseInt(hex.slice(0, 8), 16),
parseInt(hex.slice(8, 16), 16),
parseInt(hex.slice(16, 24), 16),
parseInt(hex.slice(24, 32), 16),
];
}

const [s1, s2, s3, s4] = hashToSeeds(tokenData.hash);
const rand = sfc32(s1, s2, s3, s4);

// Usage:
// rand() → float in [0, 1)
// rand() * (b - a) + a → float in [a, b)
// Math.floor(rand() * n) → integer in [0, n)
```

Alternatively, use the full `Random` class that ships in the MCP scaffold, which adds convenient helper methods:
Instead, seed a pseudo-random number generator (PRNG) from `tokenData.hash`:

```javascript
class Random {
Expand Down Expand Up @@ -255,7 +219,7 @@ Test with specific hashes by appending `?hash=0x...` to the URL. Test with many

If you have an existing p5.js or vanilla JS sketch that you want to convert to Art Blocks format:

1. **Replace `Math.random()`** with calls to your sfc32 PRNG seeded from `tokenData.hash`
1. **Replace `Math.random()`** with calls to your `Random` class PRNG seeded from `tokenData.hash`
2. **Remove CDN `<script>` tags** — the generator loads your library automatically
3. **Remove canvas creation code** — for p5.js, remove `createCanvas()` calls or use `windowWidth`/`windowHeight`; for vanilla JS, select the existing `<canvas>` instead of creating one
4. **Make dimensions relative** — replace hardcoded pixel values with percentages of `width`/`height`
Expand Down
37 changes: 2 additions & 35 deletions legacy/features-script.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,9 @@ function calculateFeatures(tokenData) {

---

## The Random Class (Legacy)
## PRNG in the Features Script

The following `Random` class was commonly used with `calculateFeatures()`. It uses the sfc32 PRNG seeded from the token hash:

```javascript
class Random {
constructor(hash) {
const hex = hash.slice(2);
this.prng = this._sfc32(
parseInt(hex.slice(0, 8), 16),
parseInt(hex.slice(8, 16), 16),
parseInt(hex.slice(16, 24), 16),
parseInt(hex.slice(24, 32), 16)
);
}

_sfc32(a, b, c, d) {
return function () {
a |= 0; b |= 0; c |= 0; d |= 0;
let t = (((a + b) | 0) + d) | 0;
d = (d + 1) | 0;
a = b ^ (b >>> 9);
b = (c + (c << 3)) | 0;
c = (c << 21) | (c >>> 11);
c = (c + t) | 0;
return (t >>> 0) / 4294967296;
};
}

random_dec() { return this.prng(); }
random_num(a, b) { return a + this.prng() * (b - a); }
random_int(a, b) { return Math.floor(a + this.prng() * (b - a + 1)); }
random_bool(p) { return this.prng() < p; }
random_choice(arr) { return arr[Math.floor(this.prng() * arr.length)]; }
}
```
The `calculateFeatures()` function must use the same pseudo-random number generator (PRNG) as the art script, seeded from `tokenData.hash` in the same way and called in the same order. This ensures that the features returned by `calculateFeatures()` are consistent with the actual visual output of the project.

---

Expand Down
Loading