From 7de21e290d2dab624e9bcdaad294ae37aa33f4a4 Mon Sep 17 00:00:00 2001 From: Tim Evans Date: Tue, 2 Jun 2026 22:40:17 +0100 Subject: [PATCH] fix: split bullet tax credit update into standalone call (v1.4.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foundry v14 rejects actor.update() silently when one field in the payload has a schema conflict. The combined update (credits + finances nested paths) was being dropped entirely, so credits never changed. Fix: two separate actor.update() calls 1. Credit deduction: update("system.details.credits") alone — critical 2. Finances tracking: update(finances paths) — non-critical, caught silently Added console.log so GMs can confirm credit deductions in browser console: Zero Engine | Bullet Tax: Joe credits 500c -> 440c (-60c) --- system.json | 2 +- zero-engine.mjs | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/system.json b/system.json index d56cde6..ef5c40d 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "zero-engine", "title": "Zero Engine (SLA Industries)", "description": "A basic game system for SLA Industries using the Zero Engine rules.", - "version": "1.4.3", + "version": "1.4.4", "compatibility": { "minimum": 13, "verified": "14.359" diff --git a/zero-engine.mjs b/zero-engine.mjs index 62bc70a..c3d670b 100644 --- a/zero-engine.mjs +++ b/zero-engine.mjs @@ -5999,6 +5999,7 @@ function _getAmmoModifiers(weaponData) { * Deduct bullet tax from actor credits and update session ammo log. * Bullet tax = 2× the base round cost (ammo purchase price + field levy). * Called immediately when a weapon fires. + * Two separate update() calls so a finances schema issue never blocks the credit deduction. */ async function _applyBulletTax(actor, weaponData, roundsFired) { if (!actor || roundsFired <= 0) return 0; @@ -6010,15 +6011,26 @@ async function _applyBulletTax(actor, weaponData, roundsFired) { const currentCredits = Number(actor.system?.details?.credits ?? 0); const newCredits = Math.max(0, currentCredits - totalCost); - // Deduct from credits; track session bullet tax - const sessionSpent = Number(actor.system?.finances?.ammoSpentSession ?? 0) + totalCost; - const bulletTaxTotal = Number(actor.system?.finances?.expenses?.bulletTax ?? 0) + totalCost; + // ── Credit deduction — critical, standalone update ────────────────────── + try { + await actor.update({ "system.details.credits": newCredits }); + console.log(`Zero Engine | Bullet Tax: ${actor.name} credits ${currentCredits}¢ → ${newCredits}¢ (−${totalCost}¢)`); + } catch (err) { + console.error("Zero Engine | Bullet Tax credit deduction failed:", err); + return 0; + } - await actor.update({ - "system.details.credits": newCredits, - "system.finances.ammoSpentSession": sessionSpent, - "system.finances.expenses.bulletTax": bulletTaxTotal - }); + // ── Finances tracking — non-critical, separate update ─────────────────── + try { + const sessionSpent = Number(actor.system?.finances?.ammoSpentSession ?? 0) + totalCost; + const bulletTaxRun = Number(actor.system?.finances?.expenses?.bulletTax ?? 0) + totalCost; + await actor.update({ + "system.finances.ammoSpentSession": sessionSpent, + "system.finances.expenses.bulletTax": bulletTaxRun + }); + } catch (_) { + // Finances tracking is optional — ignore failures silently + } return totalCost; }