Launch build: k=3 floor-weighted draw, three missions per hunter per day, HUNT_LIVE_AT lifts the curtain and opens outbound at the launch moment, badge photos to topic + general, toasts on the board
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+12
-4
@@ -15,17 +15,25 @@
|
||||
const store = require('./store');
|
||||
const { ctDay } = require('./missions');
|
||||
|
||||
const DEFAULTS = { minPol: 0.05, maxPol: 1, dailyCapPol: 20, lowBalancePol: 40 };
|
||||
// drawSkew k: log-uniform on u^(1/k), so k=1 is the plain log-uniform and k=3 leans hard to the floor
|
||||
// (mean ~0.13 POL on 0.05..1, one drip in eighty above 0.5). missionsPerDay: finds per hunter per
|
||||
// Central day (Marty, 2026-09-20: cap 40, k=3, 3 a day, so a launch morning does not empty the pool)
|
||||
const DEFAULTS = { minPol: 0.05, maxPol: 1, dailyCapPol: 20, lowBalancePol: 40, drawSkew: 3, missionsPerDay: 3 };
|
||||
function settings() { return Object.assign({}, DEFAULTS, store.read('settings', {})); }
|
||||
function setSettings(patch) { return store.update('settings', {}, s => Object.assign(s, patch)); }
|
||||
|
||||
function draw(min, max) {
|
||||
function draw(min, max, skew) {
|
||||
const lo = Math.log(min), hi = Math.log(max);
|
||||
const v = Math.exp(lo + Math.random() * (hi - lo));
|
||||
const k = Math.max(1, Number(skew != null ? skew : settings().drawSkew) || 1);
|
||||
const u = Math.pow(Math.random(), 1 / k); // k>1 pushes u toward 1, i.e. the value toward the floor
|
||||
const v = Math.exp(hi - u * (hi - lo));
|
||||
return Math.round(Math.max(min, Math.min(max, v)) * 10000) / 10000;
|
||||
}
|
||||
|
||||
// prize drips (weekly prizes) are paid from the same wallet but never count against the daily pool
|
||||
// a hunter's finds today (Central), prizes excluded
|
||||
function findsToday(memberId, day) { return store.read('payouts', []).filter(p => p.memberId === Number(memberId) && p.day === day && p.status !== 'failed' && !p.prize).length; }
|
||||
function daily(memberId) { const s = settings(); const limit = Math.max(1, Number(s.missionsPerDay) || 3); const done = findsToday(memberId, ctDay()); return { limit, done, left: Math.max(0, limit - done) }; }
|
||||
function paidToday(day) {
|
||||
return store.read('payouts', []).filter(p => p.day === day && p.status !== 'failed' && !p.prize).reduce((n, p) => n + p.pol, 0);
|
||||
}
|
||||
@@ -88,4 +96,4 @@ function totals() {
|
||||
return { paid: paid.length, pol: Math.round(paid.reduce((n, p) => n + p.pol, 0) * 10000) / 10000, queued: all.filter(p => p.status === 'queued').length, today: paidToday(ctDay()), hunters: new Set(paid.map(p => p.memberId)).size };
|
||||
}
|
||||
|
||||
module.exports = { settings, setSettings, draw, grant, completed, payable, mark, ledger, mine, totals, paidToday, pool, nextResetAt };
|
||||
module.exports = { settings, setSettings, draw, grant, completed, payable, mark, ledger, mine, totals, paidToday, pool, nextResetAt, daily, findsToday };
|
||||
|
||||
Reference in New Issue
Block a user