<aside> <img src="/icons/reorder_gray.svg" alt="/icons/reorder_gray.svg" width="40px" />
Navigation
</aside>
<aside> ⚡
Effectors are timed, rewarded-ad-gated multipliers: a HUD offer button spawns periodically, and tapping it plays a rewarded video that, on success, activates a temporary money/damage/chests-per-spawn boost.
</aside>
Effectors reuse the same ActiveEffectController timed-effect system Frenzy Mode is built on (see Frenzy Mode), keyed by each effector's own EffectId string instead of a hardcoded id.
ScriptableObject base: icon (for an HUD countdown badge), duration, offer button prefab, and an abstract EffectId. Every concrete effector inherits from it.multiplier field and a const string ID.EffectorData asset; GetRandomAvailable() picks a random one that isn't already active.GameData.EffectorOfferSpawnInterval (randomized range), it asks the database for a random available effector and instantiates its offer button. Only one offer is on screen at a time.GameData.EffectorOfferAvailableDuration, and a tap that shows a rewarded ad, activating the effector only on ad success.Activate(EffectorData) starts the matching multiplier through ActiveEffectController; GetMoneyMultiplier() / GetDamageMultiplier() / GetChestsMultiplier() are what the rest of the game reads.EffectorOfferController.TrySpawn() (called on a repeating Tween.DelayedCall loop) asks EffectorDatabase.GetRandomAvailable() for an effector that isn't already active. If one is available and no offer is currently up, it instantiates that effector's OfferButtonPrefab under offerContainer. If none is available (all active, or an offer is already showing), it just reschedules the same check for the next randomized interval - no offer means no visible failure, just silence until the next roll.
The offer button itself doesn't activate anything by tapping alone: EffectorOfferButtonBehavior.OnClicked calls AdsManager.ShowRewardBasedVideo, and only HandleAdResult(true) calls EffectorController.Activate(data). A declined or failed ad leaves the offer up, still counting down. Either the ad result or the countdown fillbar reaching zero calls onResolved, which destroys the offer and reschedules the next spawn - an offer that times out unclicked is simply lost, not re-offered immediately.