🌌 Z4 — dimensions: MY PATCHES → DIMENSIONS (framing) + dimension zero
A dimension is everything (the whole scene: routes, tweaks, grooves, tempo);
a vibe is a feeling you can hand a friend. Same /api/presets storage — this is
a framing rename, existing saves appear unchanged.
- ⚙ panel: 'MY PATCHES' → 'DIMENSIONS', copy reworked; input placeholder
'name this dimension…'.
- the load dropdown always leads with '✦ dimension zero — the empty field';
loading it calls enterZero() (the place you build from nothing).
- grimoire 'Saving your instrument' rewritten (canon = truth): the dimension /
vibe distinction, the GSV1 share code + #vibe= link, 'build a vibe, save a
vibe, share a vibe'.
Verified live (z0test): panel shows DIMENSIONS + ✨ VIBES, MY PATCHES gone,
dropdown leads with dimension zero. Console clean, syntax clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
55defaa695
commit
3654b2f6ec
@ -1123,11 +1123,13 @@
|
||||
|
||||
<div class="hr"></div>
|
||||
|
||||
<h2>Saving your instrument</h2>
|
||||
<h2>Saving your instrument — dimensions & vibes</h2>
|
||||
|
||||
<p class="lead">A patch you have played into being — the cables you dragged, the amounts you leaned, the mutes and freezes, the tempo you locked — is a whole instrument, and it deserves to survive the tab closing.</p>
|
||||
<p class="lead">A patch you have played into being — the cables you dragged, the amounts you leaned, the mutes and freezes, the tempo you locked — is a whole instrument, and it deserves to survive the tab closing. There are two sizes of keepsake: a <b>dimension</b> is <i>everything</i>; a <b>vibe</b> is a feeling you can hand a friend.</p>
|
||||
|
||||
<p>Open <b>⚙ → MY PATCHES</b> and <b>save</b>. The entire live state is written to your account, keyed to your login (<i>monsterrobotparty@gmail.com</i>): every route with its amount and curve, every group and orbit, the running mix of gains and mutes and freezes, and the godtime tempo. From any device, <b>load</b> it back and the exact instrument returns — the same planet, wired the same way, pulsing at the same locked BPM. (Locally, spells live as <kbd>patches/*.json</kbd> on the host; MY PATCHES is that same power for signed-in players, carried to your account and back.)</p>
|
||||
<p><b>Dimensions — the whole world, saved.</b> Open <b>⚙ → DIMENSIONS</b> and <b>save</b>. The entire live state is written to your account, keyed to your login (<i>monsterrobotparty@gmail.com</i>): every route with its amount and curve, every group and orbit, the running mix of gains and mutes and freezes, and the godtime tempo. From any device, <b>load</b> it back and the exact instrument returns — the same planet, wired the same way, pulsing at the same locked BPM. The top of the list is always <b>✦ dimension zero</b> — the empty field, the place you build from nothing. (Locally, spells live as <kbd>patches/*.json</kbd> on the host; DIMENSIONS is that same power for signed-in players, carried to your account and back.)</p>
|
||||
|
||||
<p><b>Vibes — a feeling, shareable.</b> A dimension is a hard scene save of the whole instrument; a <b>vibe</b> is smaller and lighter — a little bundle of specific source→voice cables, the exact combo that made a moment sing. Right-click a spinning orb in zero (or any node in the full field) → <b>💾 save as vibe</b>, or open <b>✨ vibes</b> (the zero pill, or ⚙). Applying a vibe is <i>additive</i> — it lays its cables on top of whatever you already have and can be toggled straight back off, and it never touches a cable you built by hand. Then <b>⧉ copy</b> the vibe's code (a short <kbd>GSV1…</kbd> string) and paste it to a friend, or share a <kbd>godstrument.pro/#vibe=…</kbd> link — they see <i>“someone shared a vibe”</i> and choose whether to add it. Build a vibe, save a vibe, share a vibe.</p>
|
||||
|
||||
<div class="hr"></div>
|
||||
|
||||
@ -7473,15 +7475,16 @@
|
||||
clr.onclick = () => { for (const k in midiBindings) delete midiBindings[k]; saveBindings(); midiStatusEl.textContent = "mappings cleared."; };
|
||||
panelEl.appendChild(clr);
|
||||
|
||||
// My patches — personal presets saved to your account (the full patch:
|
||||
// routes, tweaks, tempo). Sign in to save; loads restore your instrument.
|
||||
const th = document.createElement("h3"); th.textContent = "MY PATCHES"; th.style.marginTop = "8px";
|
||||
// Dimensions (Z4) — personal full-scene saves to your account (the whole patch:
|
||||
// routes, tweaks, tempo). A dimension is everything; a vibe is a feeling you can
|
||||
// hand a friend. Same /api/presets storage — this is a framing rename only.
|
||||
const th = document.createElement("h3"); th.textContent = "DIMENSIONS"; th.style.marginTop = "8px";
|
||||
panelEl.appendChild(th);
|
||||
const pMsg = document.createElement("div"); pMsg.className = "hint"; pMsg.style.margin = "2px 0 4px";
|
||||
pMsg.textContent = "your own routing, saved to your account.";
|
||||
pMsg.textContent = "your whole instrument, saved to your account. a dimension is everything.";
|
||||
panelEl.appendChild(pMsg);
|
||||
const nameRow = document.createElement("div"); nameRow.className = "row"; nameRow.style.margin = "4px 0";
|
||||
const nameIn = document.createElement("input"); nameIn.type = "text"; nameIn.placeholder = "name this patch…"; nameIn.className = "tplname";
|
||||
const nameIn = document.createElement("input"); nameIn.type = "text"; nameIn.placeholder = "name this dimension…"; nameIn.className = "tplname";
|
||||
const saveBtn = document.createElement("button"); saveBtn.textContent = "save"; saveBtn.className = "midibtn";
|
||||
saveBtn.onclick = async () => {
|
||||
const n = nameIn.value.trim(); if (!n) return;
|
||||
@ -7496,6 +7499,7 @@
|
||||
const loadBtn = document.createElement("button"); loadBtn.textContent = "load"; loadBtn.className = "midibtn"; loadBtn.style.marginLeft = "6px";
|
||||
loadBtn.onclick = async () => {
|
||||
const n = templateSelect.value; if (!n) return;
|
||||
if (n === "__zero__") { enterZero(); pMsg.textContent = "entered dimension zero — the empty field"; return; }
|
||||
const r = await gsFetch("/api/presets/" + encodeURIComponent(n), "GET");
|
||||
if (r.ok && r.data.data) { loadPatch(r.data.data); pMsg.textContent = "loaded “" + n + "”"; }
|
||||
else pMsg.textContent = "load failed";
|
||||
@ -7519,10 +7523,11 @@
|
||||
if (!templateSelect) return;
|
||||
templateSelect.innerHTML = "";
|
||||
const opt = (v, t) => { const o = document.createElement("option"); o.value = v; o.textContent = t; templateSelect.appendChild(o); };
|
||||
if (!(typeof Accounts !== "undefined" && Accounts && Accounts.user)) { opt("", "— sign in to load —"); return; }
|
||||
opt("__zero__", "✦ dimension zero — the empty field"); // always first: the place you build from nothing
|
||||
if (!(typeof Accounts !== "undefined" && Accounts && Accounts.user)) { opt("", "— sign in to load your own —"); return; }
|
||||
const r = await gsFetch("/api/presets", "GET");
|
||||
const names = (r.ok && r.data.presets) ? r.data.presets.map(p => p.name) : [];
|
||||
if (!names.length) opt("", "— none saved —");
|
||||
if (!names.length) opt("", "— none saved yet —");
|
||||
else names.forEach(nm => opt(nm, nm));
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user