atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0

Commit 08ffcd6cbba5

tarball

atagen <boss@atagen.co>2026-10-14 11:24 UTC

1 file changed+16-3
ui: show every stat's change turn by turn, and forget the combo once it is sent

A first-time player had to diff headers in the log to learn what a turn did. A preselected combo partner also carried into the next JELQ, so a later single technique silently became a combo.
Modified file: src/ui.html+16 additions−3 deletions
@@ -72,6 +72,7 @@ const STATS = [
7272 ];
7373 const MEASURED = ["x-length", "Length"];
7474 const GROWTH = new Set(["x-length", "x-self-reported-length", "x-girth", "x-foreskin"]);
75+const BETTER = { "x-length": 1, "x-self-reported-length": 1, "x-girth": 1, "x-foreskin": 1, "x-friction": -1, "x-stamina": 1, "x-suspicion": -1, "x-shame": -1, "x-cash": 1, "x-floor": 1 };
7576 let lastStats = {};
7677 const QUIET = new Set(["link", "set-cookie", "server", "x-powered-by", "cache-control", "content-length", "content-type", "date"].concat(STATS.map(s => s[0]), MEASURED[0]));
7778
@@ -216,15 +217,26 @@ function renderStats(headers) {
216217 const row = el("tr");
217218 for (const [name, label] of stats.slice(i, i + 2)) {
218219 const value = headers ? headers[name] : undefined;
219- const delta = GROWTH.has(name) ? parseFloat(value) - parseFloat(lastStats[name]) : NaN;
220- const shown = value === undefined ? "—" : value + (Math.abs(delta) >= 0.005 ? " (" + (delta > 0 ? "+" : "") + delta.toFixed(2) + ")" : "");
221- row.append(el("th", { align: "left", textContent: label }), el("td", { textContent: shown }));
220+ const cell = el("td", {}, value === undefined ? "—" : value);
221+ const changed = value === undefined ? null : change(name, value);
222+ if (changed) cell.append(" ", changed);
223+ row.append(el("th", { align: "left", textContent: label }), cell);
222224 }
223225 table.append(row);
224226 }
225227 lastStats = headers || {};
226228 }
227229
230+function change(name, value) {
231+ const before = lastStats[name];
232+ if (before === undefined || before === value) return null;
233+ if (name === "x-eq") return el("small", { textContent: "(was " + before + ")" });
234+ const delta = parseFloat(value) - parseFloat(before);
235+ if (!(Math.abs(delta) >= 0.005)) return null;
236+ const text = (delta > 0 ? "+" : "") + (GROWTH.has(name) ? delta.toFixed(2) : delta);
237+ return el("b", { textContent: text, style: "color: " + (Math.sign(delta) === BETTER[name] ? "green" : "red") });
238+}
239+
228240 function renderAlerts(list) {
229241 const box = $("alerts");
230242 box.replaceChildren();
@@ -461,6 +473,7 @@ async function go(event) {
461473 const chosen = [value("technique")].concat(names.includes("also") && value("also") ? [value("also")] : []);
462474 path += "?technique=" + encodeURIComponent(chosen.join(","));
463475 if (names.includes("intensity")) path += "&intensity=" + encodeURIComponent(value("intensity"));
476+ delete values.also;
464477 }
465478 if (key === "runs POST" && value("seed")) path += "?seed=" + encodeURIComponent(value("seed"));