Technische Referenz

My Fishing Kaktus

Mechanik-Doku für alle Systeme: Area-Werte, Rarity-Wahrscheinlichkeiten, Upgrade-Formeln, Wetter-Buffs, Karl-Rewards, Daily-Schedule, Save-Format. Kein Spielratgeber — nur Fakten und Formeln.

Stand: 25.05.2026 V1.x Active Fishing

Übersicht

My Fishing Kaktus ist ein aktives Sammel-Fischspiel. Spieler tippen auf Fischstellen, lösen ein Fang-Minispiel aus, sammeln Fische in einem Index, verkaufen sie für Coins, kaufen Upgrades und prestigen sich in tiefere Areas.

  • 3 Areas: Pond (Start), Lake (Prestige 1), Ocean (Prestige 2).
  • 132 Fische total, aufgeteilt nach Rarity in jeder Area.
  • 5 Upgrades: Rute, Schnur, Haken, Köder, Glück (max Level 5).
  • 10 Wetter-Events (5 Standard mit Buffs, Abyss + 4 Mutation-Events) — 15-min-Slots, 2,5-min aktiv.
  • Mutationen: Standard (BIG/HUGE/SHINY, 10 %) + Event-spezifisch (ABYSSAL → HAUNTED ×4–×10) — stacken multiplikativ.
  • Karl Bonus-Event mit Putz-Minispiel und Glücksrad.
  • Daily-Rewards mit Streak-System (Tag 7 = Epic, ab Woche 3 = Legendary).

Areas

Jede Area hat eigene Rarity-Gewichte, Gewichtsbereiche und Wert-Multiplikatoren. Spieler starten im Pond. Lake wird mit Prestige 1 freigeschaltet, Ocean mit Prestige 2.

AreaPrestigevalueMultupgradeMultSpawn-IntervallPrestige-Coins-Anker
Pond0×1,05×130–52 s (Basis)24.000
Lake1×0,46×626–46 s (Basis)750.000
Ocean2×0,60×1022–40 s (Basis)

valueMult kommt in die Coin-Wert-Berechnung beim Verkauf, upgradeMult macht Upgrades in höheren Areas teurer (Pond Rod L0 = 80 Coins, Lake = 480 Coins, Ocean = 800 Coins).

Spawn-Intervall ist die Basis-Wartezeit vor Köder-Upgrade — Köder reduziert pro Level (siehe Köder im Upgrades-Abschnitt).

Rarity-Gewichte (Roll-Wahrscheinlichkeiten)

Innerhalb einer Area wird beim Anangeln eine Rarity per gewichtetem Zufall bestimmt. Glück-Upgrade verschiebt die Verteilung Richtung seltene Rarities:

luckPower = 1 + glückLevel × 0.26
gewicht(rarity) = baseGewicht × luckPower ^ rarity.luckImpact
AreaCommonUncommonRareEpicLegendary
Pond80154,50,5
Lake682281,80,2
Ocean5526144,30,7

Gewichts-Bereiche (kg pro Fang)

Pro Rarity in jeder Area gibt es einen kg-Bereich. rollWeight picked aus diesem Bereich; mit 4 % Chance gibt es einen Trophy-Roll (oberste 25 % des Bereichs).

Area / RarityCommonUncommonRareEpicLegendary
Pond0,05–0,50,12–0,90,25–1,80,6–3,5
Lake0,2–1,50,5–3,21–72,5–166–38
Ocean0,8–4,52–115–3212–8530–220

Raritäten

5 Stufen, global definiert. Beeinflussen Wert, Glück-Shift und Fang-Schwierigkeit:

RarityFarbevaluePerKgluckImpactdifficulty
Common#79d9f7 (cyan)8−0,40,92
Uncommon#65e2a2 (grün)20+0,21,00
Rare#9f9dff (violett)55+0,71,12
Epic#d58cff (magenta)150+1,31,28
Legendary#ffc86c (gold)500+1,81,46

Coin-Wert-Formel

coinWert = max(1, round(kg × valuePerKg × fish.valueMultiplier × area.valueMultiplier))

fish.valueMultiplier ist pro Fisch leicht unterschiedlich (siehe Fish-Pool-Weights im Code, basiert auf Pool-Größe der Rarity in dieser Area).

Fisch-Index

Pond hat 36 Fische, Lake 44, Ocean 52 — total 132. Aufteilung nach Rarity:

AreaCommonUncommonRareEpicLegendaryTotal
Pond14108436
Lake1012128244
Ocean6121612652

Beim Fang wird ein zufälliger Fisch aus dem Area-Rarity-Pool per gewichtetem Pick gewählt (Pool-Gewichte siehe FISH_POOL_WEIGHTS). Im Fish-Index wird nur die aktuelle Area mit voller SVG-Liste gerendert, andere Areas zeigen nur den Counter (Performance).

Vollständige Fisch-Namen siehe js/data/fish.js im Code.

Upgrades

5 Upgrade-Pfade mit max Level 5. Kostensteigerung pro Level: 1,62 bis 1,72 Multiplier (variiert leicht). Skaliert mit area.upgradeMultiplier.

kaufPreis = round(baseCost × area.upgradeMultiplier × costGrowth^level)
UpgradebaseCostcostGrowthEffekt
Rute801,62Breitere Fangzone (+0,035 pro Level), reduziert Fisch-Speed um max 35 %
Schnur1101,64Reduziert Tension-Drain um 12 % pro Level (max 60 %)
Haken1501,66+15 % Fang-Balken-Fill pro Level, +35 % Tension-Refill pro Level
Glück2401,72luckPower +0,26 pro Level → seltenere Fische öfter
Köder1801,65+1 Spot Cap pro Level, +2s Lifetime pro Level, -1s Spawn-Wait pro Level

Rute (Fish-Speed-Modifier)

rodSpeedMult = max(0.65, 1 − rodLevel × 0.06)   // L0=1.0 ... L5=0.70 (Cap)
rodTurnMult  = 1 + rodLevel × 0.08              // L0=1.0 ... L5=1.40

Köder (Spawn + Spot-Lifetime)

Handpicked-Tuning für klar spürbare Progression pro Level. Lookup-Tabelle:

LevelMax Spots parallelLifetimeSpawn-Wait
L015 s6 s
L127 s5 s
L239 s4 s
L3411 s3 s
L4513 s2 s
L5615 s1 s

nextDelay = waitSec / spawnMultiplier — kein + lifetimeSec, sodass Spots sich überlappen und der maxSpots-Wert tatsächlich greift. Bei L5 spawnt alle 1 s ein neuer Spot, jeder lebt 15 s → bis zu 6 parallel sichtbar.

Visuelle Angel-Themes pro Area

Im Angel-UI (Shop) wird eine SVG-Angel gerendert, deren Look pro Area und Upgrade-Level wechselt. Architektur in js/systems/angel/ (Composer + Themes + Shapes).

AreaRodGripReelHookBaitAura
Pondclassiccorkspinningjspinnernone
Lakedriftwoodwrapflybarbedflyleaves
Oceantacticalrubberbaitcastertreblejigbubbles

Neue Areas brauchen nur einen Daten-Block in themes.js — keine neue Render-Logik. Shape-Slots: rod/grip/reel/eyelet/hook/bait/aura mit je 2-5 Varianten; weitere Auras (embers, runes) sind für künftige Areas (Volcano, Cosmic) schon vorbereitet.

Fang-Minispiel

Beim Antippen einer Fischstelle öffnet sich das Minispiel mit zwei Bars: Fang-Fortschritt (oben, grün/blau/gold) und Schnur-Spannung (unten, rot).

Fang-Fortschritt

Steigt wenn der Fisch in der grünen Catch-Zone ist, fällt sonst. Bei 100 % = Catch.

catchSpeed = (0.3 + hookLevel × 0.045) / rarity.difficulty
lossSpeed  = max(0.035, 0.13 × rarity.difficulty × (1 − lineLevel × 0.11))
zoneWidth  = min(0.44, 0.19 + rodLevel × 0.035)

Schnur-Spannung

Startet bei 1.0. Drainet wenn Fisch ausserhalb der Zone, refillt wenn drinnen. Bei 0 → Catch verloren.

tensionDrain = max(0.04, TENSION_DRAIN[rarity] × (1 − lineLevel × 0.12))
tensionRefill = 0.36 × (1 + hookLevel × 0.35)
RarityDrain/s (L0)~Sek. bis Ausriss (L0)~Sek. bis Ausriss (Line L5)
Common0,1676,0 s15,0 s
Uncommon0,214,8 s11,9 s
Rare0,273,7 s9,3 s
Epic0,342,9 s7,4 s
Legendary0,422,4 s6,0 s

Fisch-Bewegung pro Rarity

// Speed = (baseSpeed + rand × speedVariance) × rodSpeedMult
// TurnIn = (minTurn + rand × (maxTurn − minTurn)) × rodTurnMult
// Beim Turn: flipChance = Wahrscheinlichkeit für Richtungswechsel
RaritybaseSpeedspeedVarianceminTurn (s)maxTurn (s)flipChance
Common0,100,060,701,6045 %
Uncommon0,140,100,551,3555 %
Rare0,220,140,401,0565 %
Epic0,300,180,280,8572 %
Legendary0,420,220,200,6878 %

Coin-Fische (Timer-Fische)

Schwimmen ab und zu durchs Wasser. Klick = direkter Coin-Reward. Vier Tiers (small / big / sword / shark) mit unterschiedlichen Reward-Tabellen pro Area:

Area / Tiersmallbigswordshark
Pond82350107
Lake46138300632
Ocean1.3003.9008.60018.000

Wetter-Events

Global synchron für alle Spieler. Slot = 15 Minuten, davon 2,5 Minuten aktiv. Buff wird multiplikativ auf den entsprechenden Stat angewendet. Slot-Bestimmung per deterministischem Hash vom Epoch-Index.

EventWeightChanceEffektWasser-Look
☀ Sonniges Wetter2016,7 %luck ×2 · SUNNY-Mutation ×2 (20 %)Calm preset, helles Licht
🌧 Regenschauer2016,7 %spawnRate ×2 · WET-Mutation ×2 (20 %)Rain im Shader
⛈ Sturm2016,7 %hook ×2 · STORMY-Mutation ×2 (20 %)Storm preset, Sturm-Wellen + Regen
🌫 Nebel2016,7 %rod ×2 · MISTY-Mutation ×2 (20 %)Weißer Nebel-Overlay
🌙 Nachtangeln2016,7 %line ×2 · NOCTURNAL-Mutation ×2 (20 %)Deepsea preset, Night-Veil
🌌 Abyss54,2 %Epic+ ×2 · ABYSSAL-Mutation ×4 (15 %)Tiefblauer Veil + Neon-Partikel
🌠 Polarlicht65,0 %AURORA-Mutation ×3 (30 %)Grün-violetter Schleier + drifting Wisps
🔥 Glutsturm43,3 %EMBER-Mutation ×5 (25 %)Storm-Wasser + orange Glut-Funken
🌑 Blutmond32,5 %CRIMSON-Mutation ×7 (20 %)Deepsea + tiefroter Schleier
👻 Geistermeer21,7 %HAUNTED-Mutation ×10 (15 %)Deepsea + cyan Geister-Wisps von oben

Event-Pick: hash(slotIndex) % totalWeight (total = 120), dann gewichtetes Bucket-Mapping. Neue seltene Events einfach mit kleinem weight in WEATHER_EVENTS ergänzen.

Abyss-Spezial: Statt einen Minispiel-Stat zu boosten, multipliziert es direkt die Roll-Wahrscheinlichkeit für Epic- und Legendary-Rarities (Logik in weatherEventSystem.getRarityMultipliers()). Zusätzlich Chance auf ABYSSAL-Mutation.

Mutation-Only Events: Polarlicht / Glutsturm / Blutmond / Geistermeer haben keinen Stat-Buff — ihre einzige Wirkung ist die jeweilige Event-Mutation während der 5-Min-Phase. Je seltener das Event, desto höher der Multiplier (Polarlicht ×3 → Geistermeer ×10). Details s. Mutationen.

Buffs gehen direkt in die Minispiel-Bonus-Berechnung — z.B. „Sturm" verdoppelt den effektiven Hook-Level, was sowohl Fang-Speed als auch Tension-Refill steigert.

Mutationen

Bei jedem Fang werden unabhängig zwei Würfe gemacht: Standard-Mutation (immer, 10 %) und Event-Mutation (nur während eines passenden Wetter-Events). Beide können gleichzeitig zuschlagen → multiplikativ stackbar. Der finale Coin-Wert ist base × prod(mutations.mult).

Standard-Mutationen (immer würfelbar)

P(standard) = 10 % × (1 + Glück × 0.08)
Pool (gewichtet): BIG 65 / HUGE 25 / SHINY 10
IDNameMultiplierPool-AnteilChance Glück Lvl 0Chance Glück Lvl 5
bigBIG×1,565 %6,5 %9,1 %
hugeHUGE×2,025 %2,5 %3,5 %
shinySHINY 🌟×3,010 %1,0 %1,4 %

Glück-Bonus: jedes Level Glück (max 5) erhöht alle Mutationen-Wahrscheinlichkeiten um +8 % (sanft). Bei Lvl 5: ×1,40 auf alle Mutationen.

Event-Mutationen (nur während aktivem Event)

Jedes der 10 Wetter-Events hat eine eigene Mutation. Standard-5 ×2 (zusätzlich zum Stat-Buff), Rare-5 ×3 bis ×10. In-Event-Chance ist die Wahrscheinlichkeit pro Catch während das Event läuft, "Über-alles-Chance" rechnet das mit der Slot-Häufigkeit hoch.

EventMutationMultin-Event-ChanceÜber-alles-Chance
☀ Sonniges WetterSUNNY×220 %~3,3 %
🌧 RegenschauerWET×220 %~3,3 %
⛈ SturmSTORMY×220 %~3,3 %
🌫 NebelMISTY×220 %~3,3 %
🌙 NachtangelnNOCTURNAL×220 %~3,3 %
🌌 AbyssABYSSAL×415 %~0,63 %
🌠 PolarlichtAURORA×330 %~1,5 %
🔥 GlutsturmEMBER×525 %~0,83 %
🌑 BlutmondCRIMSON×720 %~0,5 %
👻 GeistermeerHAUNTED×1015 %~0,25 %

Stacking-Beispiel: Du fängst während Geistermeer (1,7 % Slot) einen Common-Fisch (10 Coins base). Du würfelst SHINY (×3) UND HAUNTED (×10) → finaler Wert 10 × 3 × 10 = 300 Coins. Die seltensten Catches überhaupt im Spiel.

Event-Mutationen Glück-Skalierung (analog Standard): jeweilige in-Event-Chance × (1 + Glück × 0,08). Bei Lvl 5: HAUNTED-Chance steigt von 15 % auf 21 % innerhalb von Geistermeer.

Was ist die seltenste Catch-Kombi?

Theoretisches Optimum: Legendary + SHINY + HAUNTED + ≥99 % kg während Geistermeer aktiv.

  • P(Legendary) ohne Glück: 0,5 %, mit Glück Lvl 5 (Luck-Boost auf Rarity): ~2,3 %
  • P(SHINY): 1 % (Lvl 0) / 1,4 % (Lvl 5)
  • P(HAUNTED): 0,25 % (Lvl 0) / 0,35 % (Lvl 5)
  • P(kg ≥ 99 %): ~0,8 %

Kombiniert ohne Glück: ~1 in 1 Milliarde (1 / 1.000.000.000). Mit Glück Lvl 5 auf den Rarity- und Mutation-Buffs zusammen: ~1 in 110 Millionen. Das wäre der absolute Trophäen-Fang — praktisch nicht erreichbar ohne forciertes Spielen aller Geistermeer-Events.

P(SHINY HAUNTED) im Detail: Pro Catch während Geistermeer 1 % × 15 % = 0,15 %. Pro 15-Catch-Window ~2,2 %. Geistermeer triggert ~0,8 mal/Tag → bei aktivem Mitgrinden aller Events erwartet man ein SHINY HAUNTED nach ~3 Wochen, 95 % nach ~170 Tagen.

Implementation: rollMutations(event) in data/mutations.js wird beim Cast in startFishing() aufgerufen, das Ergebnis fliesst per applyMutationsToCandidate direkt in candidate.value. Anzeige als Badges (Glow für SHINY + alle Event-Mutationen) über dem Fischnamen, plus Broadcast-Push an alle Spieler bei Event-Mutationen und SHINY.

Karl die Schildkröte

Bonus-Event. Karl taucht maximal 1× pro Stunde auf, zu einer deterministisch-zufälligen Sekunde innerhalb der Stunde (global synchron). Sichtbar für 30 Sekunden — wer nicht antippt, verpasst ihn.

KARL_SLOT_MS = 3.600.000   // 1 Stunde
KARL_VISIBLE_MS = 30.000   // 30 Sekunden
appearOffset = hash(slotIndex) → zwischen 60s und (SLOT_MS − VISIBLE_MS − 60s)

Cleaning-Minispiel

  • Karls Panzer ist mit braun-grünem Schmutz bedeckt (Karl-Silhouette als Mask).
  • Spieler wischt mit Maus/Finger → destination-out Erase auf dem Canvas.
  • Brush-Radius: 5.5 % der Canvas-Breite.
  • Tolerance: 93 % Sauberkeit → Cleaning fertig.

Glücksrad-Belohnungen

Pro Area unterschiedliche Reward-Tabelle. Gewichte = Häufigkeit:

AreaBelohnungen (Gewicht: Reward)
Pond30: +10 · 25: +25 · 20: +50 · 15: +100 · 7: +250 · 3: ★ Epic-Spot
Lake25: +50 · 25: +150 · 20: +400 · 15: +800 · 10: +1.500 · 5: ★ Epic-Spot
Ocean22: +200 · 22: +600 · 20: +1.500 · 15: +4.000 · 10: +10.000 · 8: ★ Epic · 3: ★ Legendary

Daily Rewards

Streak-System. Pro täglichem Login wird belohnt; ein verpasster Tag resettet den Streak. Basis lokales Datum (Spieler-Zeitzone, nicht UTC).

Reward-Formel

dayInWeek = ((streakDay − 1) mod 7) + 1   // 1..7
weekNum = ceil(streakDay / 7)              // 1, 2, 3, ...

dayMultipliers = [1, 1.5, 2.2, 3.2, 4.5, 6.0, 8.0]   // Tag 1..7

baseCoins(week 1) = 50
baseCoins(week 2) = 90
baseCoins(week 3) = 140
baseCoins(week 4+) = min(2500, 140 × 1.12^(weekNum − 3))

coins = round(baseCoins × dayMultipliers[dayInWeek − 1])

Tag-7 Spezial

  • Woche 1: 1× Epic-Fischstelle
  • Woche 2: 2× Epic-Fischstelle
  • Woche 3+: 1× Legendary-Fischstelle

Beispiel-Werte

TagWocheCoinsSpezial
1150
71400Epic-Spot
1427202× Epic-Spot
2131.120Legendary-Spot
7010~2.475Legendary-Spot
10515~4.360Legendary-Spot

Daily-Spawned Fischstellen bleiben 90 Sekunden sichtbar (statt 12 s wie reguläre Force-Spawns) damit niemand seine Belohnung verpasst.

Admin-Events (Live-Push)

Admins können globale Events an alle Online-Spieler pushen. Events laufen über die Supabase-Tabelle admin_game_events, Auto-Expire nach 60 s.

EventEffekt
weather-{sunny,rain,storm,fog,night,abyss,polarlicht,glutsturm,blutmond,geistermeer,clear}Forciert das Wetter-Event
spawn-fish-{small,big,sword,shark}Spawnt einen Coin-Fisch im Tier
broadcastEigener Text im Broadcast-Feed (max 200 Zeichen)
force-spawn-{epic,legendary}Garantierte Fischstelle dieser Rarity (12 s sichtbar)
spawn-karlKarl die Schildkröte spawnen
force-reloadAlle Clients reloaden nach 1,5 s (cross-game)

Prestige

Spieler prestigen sich in die nächste Area. Cap aktuell bei Prestige 2 (Ocean = letzte Area). Anker-Werte für „Du kannst jetzt prestigen":

  • Pond → Lake: erst möglich ab 24.000 Coins totalEarned
  • Lake → Ocean: erst möglich ab 750.000 Coins totalEarned

Was bleibt / wird zurückgesetzt

Bleibt

  • Fish-Index (alle gefangenen Fische)
  • Stats (totalCaught, bestCatchValue, bestWeightKg)
  • Prestige-Zähler
  • Unlocked Areas
  • Daily-Streak

Zurückgesetzt

  • Coins (auf 0)
  • Alle 5 Upgrades (auf Level 0)
  • Inventar (verkauft / verworfen)

Save-Format (game_saves Tabelle)

Im Supabase-Save (game_id = my-fishing-kaktus) wird gespeichert:

{
  version: 1,
  coins: 0,
  currentArea: "pond",
  unlockedAreas: ["pond"],
  prestige: 0,
  upgrades: { rod: 0, line: 0, hook: 0, luck: 0, sonar: 0 },  // sonar = Köder intern
  inventory: { [fishId]: { count, totalKg, totalValue, bestKg } },
  index: { [fishId]: { count, bestKg } },
  stats: {
    totalCaught: 0,
    totalSold: 0,
    totalCoinsEarned: 0,
    bestCatchValue: 0,
    bestWeightKg: 0
  },
  settings: { reducedMotion: false },
  daily: {
    streak: 0,
    lastClaimedDay: null,    // "YYYY-MM-DD" (lokal)
    totalClaimed: 0,
    bestStreak: 0
  }
}

total_earned Spalte in der Tabelle wird mit stats.totalCaught synchronisiert (für die Rangliste-Sortierung als Sekundär-Schlüssel hinter Prestige).