Changelog
← Back to Bitterballen.nu
2026-02-24
Changed: Power-ups & Skill Tree Polish
- Removed cooldowns from all power-ups — only restriction is one of each type active at a time
- Patat Met now unlocks at 100 bitterballen (was 200)
- Power-up Winkel shows "Blijf bakken om power-ups te unlocken!" when no power-ups available yet
- Uitrusting (Equipment) branch hidden for new players — only shown if player owns old shop items
- Removed main screen Ko-fi donation link (kept in panels)
2026-02-22
New: Consumable Power-ups & Quick-Access Bar
- 7 consumable power-ups in the new Power-up Winkel — buy them, stock them, activate when you need the boost
- 🍟 Patat Met — x2 click power (15s), unlocks at 100
- 🌶️ Zakje Currysaus — x2 auto production (20s), unlocks at 1K
- 🥜 Bakje Pindasaus — x1.5 click + x1.5 auto (15s), unlocks at 5K
- 🌭 Frikandel Speciaal — instant: +60s of auto production as score, unlocks at 15K
- 🐻 Berenhap — x5 click power (10s), unlocks at 50K
- 🍽️ Bittergarnituur XXL — x3 all production (12s), unlocks at 200K
- 👑 Kapsalon — x5 click + x5 auto + 25% fever duration (8s), unlocks at 1M
- Costs escalate per purchase:
floor(baseCost × mult^totalBought), Winkelkorting skill gives 10% discount
- Multiple power-ups stack multiplicatively — no cooldowns, but only one of each type active at a time
- Shows "Blijf bakken om power-ups te unlocken!" when no power-ups available yet
New: Quick-Access Bar
- Fixed bottom-center quickbar appears when first power-up unlocks
- Slots show emoji, inventory count badge (orange), and a timer bar (green = active)
- Keyboard shortcuts 1–7 activate power-ups on PC (disabled when modals/inputs are focused)
- Desktop shows shortcut key labels (top-left of each slot); hidden on mobile
- Glassmorphism styling with backdrop blur
- Mobile responsive: repositions above game-buttons, smaller 40px slots
Changed: Shop → Power-up Winkel + Equipment Branch
- Winkel tab renamed to "Power-up Winkel" (EN: "Power-up Shop") — now exclusively for consumable power-ups
- Old shop items (Dubbele Portie, Airfryer, Mini Frituur, etc.) moved to a 4th "Uitrusting" (Equipment) column in the Vaardigheden (Skills) tab
- Equipment items still purchased with bitterballen using the same cost formula
- Skill tree grid expanded from 3 to 4 columns (1fr each on desktop, 1fr on mobile)
- Equipment nodes styled with orange accent (matching game brand color)
- Old shop item unlock notifications removed (power-up unlocks have their own toasts)
New: Major Update Popup
- Existing players see a one-time popup explaining the big changes and offering to reset for the best experience
- Players can choose to start fresh or keep their current save
Changed: Kapsalon + Fever Interaction
- When Kapsalon power-up is active and Frikandel Fever triggers, fever duration is extended by 25% (5s → 6.25s)
- Fever timer bar uses actual extended duration for accurate progress display
2026-02-18
New: Passive Income Boost Items
- Snackbar Keten (Snackbar Chain) — +500 bitterballen per seconde per stuk
- baseCost: 500K, costMultiplier: 2.5, unlocks at 100K score
- High-tier flat auto producer to bridge the gap between Factory (+100/sec) and multiplier items
- Turbo Frituur (Turbo Fryer) — x2 automatische productie per stuk
- baseCost: 5M, costMultiplier: 3.5, unlocks at 1M score
- Multiplicative auto power doubler (like Grote Frituur but for passive income)
- Stacks multiplicatively: 3 Turbo Frituurs = 8x auto production
- Debuff: drops to x1.5 per unit when Nachtploeg is owned
- Nachtploeg (Night Shift) — Auto productie krijgt +0.1% van je klik power per stuk
- baseCost: 1B, costMultiplier: 8.0, unlocks at 50M score
- Bridges click and auto scaling — the more click power you have, the more passive income Nachtploeg provides
- Click power changes automatically update auto power when Nachtploeg is owned
- Debuff: each Turbo Frituur reduces Nachtploeg effectiveness by 15%
- Mutual debuff — Turbo Frituur and Nachtploeg weaken each other when both are owned, creating a strategic trade-off between flat auto multipliers and click-linked scaling
- Anti-tamper validation updated to account for all three new items and the debuff mechanics
2026-02-13
New: Donate Button & Modal
- ❤️ button in top-right corner, below audio and language toggles
- Opens a friendly non-intrusive donation modal with Ko-fi and Discord links
- Dismiss via × button, backdrop click, or "Nee bedankt, ik bak door!" / "No thanks, I'll keep frying!"
- Full i18n support (Dutch + English)
New: Changelog Button in Achievements Panel
- 📋 Bekijk changelog button added at the bottom of the achievements modal
- Orange-accented style consistent with the game's design
- Opens changelog page in a new tab
Changed: Version Link in Shop
- Version string in the shop footer is now clickable, linking to the changelog page
- Subtle hover effect (orange text + underline)
Changed: Changelog Page
- Added donation banner at the top with Ko-fi and Discord buttons
- Ko-fi button in red, Discord button in brand purple
New: Version Tracking & Update Notification
- Version check on load — stores current version in localStorage (
bitterballen_version); on reload, compares against running version
- Returning players see a dismissable toast banner when a new version is deployed
- First-time players (no stored version) see nothing
- Toast shows 🆕 icon, version string, and a link to the changelog page
- Auto-dismisses after 10 seconds, or click × to close immediately
- Full i18n support (Dutch + English)
- Changelog page (
changelog.html) — standalone dark-themed page with full release history
- Build script injects real version into JS constant and copies changelog to dist/
New: "Ballen Hoog Houden" Juggle Minigame
- Juggle minigame — tap bitterballen to keep them in the air before they hit the ground
- New ball spawns every 5 seconds; 3 misses = game over
- Canvas-based physics with gravity, horizontal bouncing, and rotation
- Reward: max balls in air x5 click multiplier boost for 30 seconds (applies to clicks and auto-production)
- Green-themed boost timer bar appears during boost
- Gated behind Nationale Hap level (index 3, 10M score); 25% chance in random minigame selection
- Guided tour on first play (3 steps explaining mechanics and reward)
- Two new achievements: "Jongleur" (3+ balls, blue tier) and "Cirque du Bitterbal" (5+ balls, purple tier, hidden)
- Full i18n support (Dutch + English)
- Mobile-safe: touch-action manipulation, context menu prevention, pointer events
- Devtools: "Start Juggle Minigame" button, juggle boost status in live stats
Fixed: Accidental Minigame Activation on iOS
- Rapid tapping on mobile could trigger the hold-to-play minigame because iOS fires
pointerup/pointercancel with mismatched pointer IDs during fast touch sequences
- Added
activePointerId tracking so only one pointer is tracked at a time; stale pointers are cleaned up instead of permanently blocking input
- Raised
HOLD_THRESHOLD from 500ms to 700ms to give mobile players more room before a tap becomes a hold
- Hold timeout callback now verifies the originating pointer is still active before starting a minigame
Fixed: Bitterbal Locking Up After Catching Frikandel/Kroket on iOS
- After catching a frikandel mid-tap, the bitterbal would permanently stop responding to clicks while frikandellen still worked
- Cause:
activePointerId guard was too strict — handlePointerEnd rejected events with mismatched pointer IDs, leaving the tracked pointer permanently stuck
- Fix:
handlePointerEnd now unconditionally clears activePointerId; handlePointerStart cleans up stale pointers instead of rejecting new ones
Fixed: Android Long-Press Context Menu During Minigames
- Long-pressing during the cooking or mosterd minigame on Android triggered the browser's native "Save image / Share" context menu
- Added
touch-action: manipulation, -webkit-touch-callout: none, and user-select: none CSS to both .cooking-minigame and .mosterd-minigame
- Added
contextmenu event listeners on both minigame overlays to preventDefault()
Fixed: Cooking Minigame — Tour Starting the Fry Timer
- When the cooking minigame tour appeared for the first time, the fry timer started immediately because
isHolding was still true from the bitterbal hold that triggered the minigame
startCookingMinigame() now resets isHolding, clears holdTimeout, and removes the holding CSS class before showing the tour or starting stage 1
Fixed: Cooking Minigame — Bitterbal Interaction During Stages 2 & 3
- During the sauce and cooling stages, pointer events on the bitterbal could still fall through to
doClick() or interfere with cooking state
handlePointerEnd now returns early during any active cooking stage (not just stage 1), since all cooking stages handle their own pointer events on the cooking overlay
Changed: Autoclicker Detection — Hard CPS Cap at 25
- Autoclickers with randomized intervals could bypass the coefficient-of-variation check
- Added a hard cap: mean click interval below 40ms (25+ CPS) now triggers the autoclicker penalty immediately, regardless of variance
- Original behavioral check (low CV + high speed) still catches slower robotic clickers
2026-02-07
New: Medium Rare (Shop Item)
- Milestone item — buy once, unlocks at 75M score
- Halves the fastfood click threshold (15 → 8 clicks needed in 3s window)
- Fastfood meter fills 2x faster, making it easier to sustain and earn chests
New: Kroket Powerup
- Rare variant of frikandel — spawns 1 in 10 times instead of frikandel
- 25x multiplier during Kroket Koorts (vs frikandel's 10x), same 5-second duration
- 220px clickable powerup with golden glow, 12 animated radiating streaks
- Mini kroketten during fever are 3x larger than mini frikandellen (240px vs 80px)
- "KROKET IS GROTE BITTERBAL" marquee scrolls across the screen at 25% opacity during kroket fever
- Fever timer label switches to "KROKET KOORTS!" / "KROKET FEVER!"
- Spawnable from devtools panel ("Spawn Kroket" button)
New: Achievement — "Best Druk in je Eentje"
- 🤹 Click frikandel, refresh frituurvet, click bitterbal, and complete minigame — all within 30 seconds
- Runtime tracker (not persisted) stores timestamps of each action; checks if all 4 fit in a 30s window
New: Achievement — "Kroket is Gewoon een Grote Bitterbal"
- 🥟 Unlocks on first kroket click
New: Achievement Tier System (WoW-style Rarity)
- Achievements now have colored borders/glow based on rarity tier
- Gray (Common) — basic first-time actions (first click, first fever, etc.)
- Green (Uncommon) — moderate milestones (100 clicks, airfryer, etc.)
- Blue (Rare) — harder milestones (1k+ clicks, perfect dip, etc.)
- Purple (Epic) — difficult challenges (50k+ clicks, Hold my Biertje, Best Druk, etc.)
- Orange — extreme achievements (1M clicks, Bek Verbrand, Vette Shit)
- Legendary — Fried Mind only (ultimate achievement, extra glow)
- Applied to both achievement panel cards and share card pills
Changed: Frietpan Frank Reworked
- New buff: Frituurvet decay rate halved (0.25%/sec → oil lasts 2x longer)
- Removed: Mini Fryer 2x bonus and Airfryer 60-second penalty
- Unlock: Now requires 150k score (unlocks alongside frituurvet instead of at 1k)
Fixed: Share Score Crashing with Achievements
btoa() threw DOMException when share payload contained emoji characters (from achievement icons)
- Replaced with UTF-8-safe
b64Encode/b64Decode helpers
- Verify function has fallback for old payloads encoded with plain
btoa
Changed: Share Verification Code Optional
[BB:...] signed payload no longer included in share text by default
- Checkbox "Voeg verificatiecode toe" / "Include verification code" in share modal to opt-in
- Share card achievements now displayed centered in their own rounded box
New: Internationalization (i18n)
- Language Toggle in header — flag button (🇳🇱/🇬🇧) switches between Dutch and English
- Full English translation of all UI text: shop items, achievements, tour steps, modals, timers, celebrations, minigames
data-i18n / data-i18n-html / data-i18n-placeholder attributes on static HTML elements
t(key) translation function with flat key lookup (STRINGS.nl / STRINGS.en)
getItemName() / getItemDesc() / getLevelName() helpers for array-based content
- Language preference persisted in localStorage (
bitterballen_lang)
- Dutch remains the default language
Fixed: Cheat Detection False Positives (VALSSPELER)
- Root cause: Runtime delta check used current multiplier state, but buffs (fever/werpen/mustard) could expire mid-interval causing under-estimation of legitimate score
- Fix: Added
resetIntegrityTracking() — resets score baseline and timestamp whenever any buff starts or ends
- Called at: fever start/end, mustard start/end, werpen buff start/end, chest completion, BekVerbrand/VetteShit unlock
- Increased headroom from 3x to 5x as additional safety margin
New: Share Score & Achievements
- Share Button in shop panel — opens share modal with visual stats card
- Stats Card — shows score, level, achievements, clicks, click power, auto power, and special badges (Bek Verbrand / Vette Shit)
- Copy to Clipboard — copies human-readable stats + signed payload
[BB:<base64>] for verification
- Native Share — uses Web Share API on supported devices (mobile)
- Verify Section — paste someone's shared score to verify authenticity via FNV-1a checksum signature
- Share data is signed with the same anti-tamper checksum; tampering with the payload invalidates the signature
2026-02-06
New: Anti-Tamper System (3-Layer Protection)
- Layer 1: Save Integrity — Game saves are signed with an obfuscated FNV-1a checksum; tampering with localStorage JSON triggers penalty
- Old saves (without checksum) are migrated automatically on first load
- Layer 2: Runtime Monitoring — Periodic (every 5s) validation that score deltas are plausible given click power, auto power, active multipliers, and elapsed time
- Also validates that clickPower and autoClickPower match item-derived calculations
- 3x headroom to prevent false positives during legitimate extreme play (fever + werpen + vetteShit = 500x)
- Layer 3: State Integrity — Periodic checks that state object properties haven't been replaced with getters/setters via Object.defineProperty
- Penalty: VALSSPELER! — On tamper detection: full-screen red overlay with "VALSSPELER!" text, save wiped, game blocked for 1 minute (persists across reload)
- Dev mode (devtools.js loaded) bypasses all anti-cheat checks
Fixed: Mobile Double-Tap Zoom
- Added
touch-action: manipulation to body — prevents double-tap zoom while preserving pan and pinch-zoom
Changed: Autoclicker Detection Sensitivity
- Reduced sensitivity: raised max CV threshold from 0.12 to 0.18 and minimum clicks from 30 to 40
New: Bek Verbrand (4th Star Ultimate Tier)
- After completing 3 full fastfood cycles (12 chests: 0→A→B→C × 3), a 4th star appears — bigger, pulsing, beckoning
- Player must sustain 100% fastfood tempo for 3 minutes to unlock
- Rewards permanent 5x click multiplier (applies to both manual clicks and auto production)
- Extravagant celebration: rainbow overlay, 24 god rays, 32 sparkles, 45 flying bitterballen, screen shake
- "BEK VERBRAND!" reveal text with "5x CLICK POWER — VOOR ALTIJD!" sub-text
- Achievement: "Bek Verbrand" — one-time unlock, persists across sessions
New: Vette Shit (5th Star Mega-Ultimate Tier)
- After Bek Verbrand, player must complete 3 more full cycles (12 more chests) to reveal the 5th star
- 5-minute sustained fastfood tempo challenge
- Rewards permanent 25x click multiplier (replaces the 5x from Bek Verbrand)
- Insane 12-second celebration: background flips via CSS transforms, repeated screen shakes, 36 rainbow god rays, 3 waves of 88 sparkles, 120 bitterballen + 80 frikandellen flying everywhere
- "VETTE SHIT!!!" reveal text with rainbow cycling
- After completion, fastfood tier counters reset to 0 and tier stays on C
- Achievement: "Vette Shit" — one-time unlock, persists across sessions
New: Autoclicker Detection
- Detects autoclickers by measuring click timing consistency (coefficient of variation) over 20 seconds
- If CV < 0.12 across 30+ clicks, triggers penalty: large carrot emoji overlay with "autoclickers mogen alleen wortels"
- Initial penalty: 10 seconds; re-detection during penalty doubles the duration
- Clicking is disabled during penalty
New: Bitterballen Werpen Minigame
- Added second minigame "Bitterballen Werpen" (throwing) alongside "Mosterd Dippen"
- When minigame charge fills and player holds, a random game is picked (50/50)
- Werpen is a power meter: hold to charge throw power, release for distance
- 0-65%: Weak throw (5-30m)
- 65-85%: Strong throw (35-50m, peak at 75%)
- 85-100%: Overshoot (25-10m, too much power)
- Distance converts to click multiplier (distance / 25, max 2.0x) active for 10 seconds
- Buff stacks with fever, mustard, and auto-clicker production
- Green/blue themed UI with countdown timer bar
- Added "Eerste Worp" achievement
- Ready indicator text changed to generic "Houd ingedrukt om te spelen"
New: Nationale Hap Level
- Added 4th level "Nationale Hap" unlocking at 10M bitterballen
- Uses
/img/levels/foebele.png as background
- Introduces dual frituurvet: two oil pans that decay independently
- The best (highest) pan counts for the production multiplier
- "Ververs" button refreshes whichever pan is lower
- Second pan bar appears side-by-side when reaching this level
Changed: Frituurvet Cost Scaling
- Frituurvet refresh cost now scales to 5% of current score (minimum 500)
- Button text updated to "Ververs (kost X)" to clarify it's a cost
Fixed: Tour Popups Not Triggering
- Fixed fastfood tour not appearing when the meter first unlocks
- Root cause:
addScore() was showing the fastfood meter before the tour wrapper in trackFastfoodClick() could detect the hidden-to-visible transition
- Removed duplicate meter show logic from
addScore(), letting trackFastfoodClick() handle it
Fixed: Minigame Result Blocking Clicks
- Added
pointer-events: none to mosterd and werpen result popups
- Result text no longer blocks clicks on the bitterbal underneath
DevTools
- Added "Trigger Werpen" button
- Added "Fastfood Tier Up" button to advance fastfood tiers for testing
- Added "Fastfood Easy (1s)" button — sets all tier durations (including Ultimate and Mega) to 1 second
- Added "Trigger Bek Verbrand" button
- Added "Trigger Vette Shit" button (rainbow gradient styling)
- Added "Autoclicker Detected" button to simulate autoclicker penalty
- Panel now scrollable with max 75% viewport height
- Added
bekverbrand, vetteshit to unlock-all achievements list
- Added
bekVerbrandUnlocked, vetteShitUnlocked to reset
- Added
werpen1 to unlock-all achievements list
- Added
werpenCount to achievement stats reset