Perk Runtime Reference¶
This page documents runtime location evidence for each perk in:
- Original: Crimsonland v1.9.93 (
analysis/ghidra/raw/crimsonland.exe_decompiled.c) - Rewrite parity implementation: Python port (
src/)
For gameplay effects and mechanics, see Perks.
For rewrite ID/name mapping, see src/crimson/perks/ids.py.
For decompile constants/addresses, see Detangling notes.
Notes:
- Many perk effects are implemented by a small set of hot paths in the original:
perk_apply(0x004055e0),perks_update_effects(0x00406b40),player_update(0x004136b0),player_fire_weapon(0x00444980),player_take_damage(0x00425e50),creature_update_all(0x00426220),creature_apply_damage(0x004207c0),projectile_update(0x00420b90), and rendering passes. - In the rewrite, perk counts live on
PlayerState.perk_countsand are typically treated as shared state across players (synced from player 0).
0. AntiPerk (PerkId.ANTIPERK)¶
Original¶
perk_can_offer(0x0042fb10): explicitly rejectsperk_id_antiperk.
Rewrite¶
src/crimson/perks/availability.py:perk_can_offer()rejectsPerkId.ANTIPERK.
1. Bloody Mess / Quick Learner (PerkId.BLOODY_MESS_QUICK_LEARNER)¶
Original¶
- Kill XP: creature death handling (via
creature_update_all→creature_handle_deathpath). - Hit FX: projectile hit handling queues extra decals / blood splatter when the perk is active and blood is enabled.
Rewrite¶
- XP multiplier on kill:
src/crimson/creatures/runtime.py:CreaturePool._start_death(). - Extra hit decals/blood:
src/crimson/game_world.py:GameWorld._queue_projectile_decals(). - Name/description toggle:
src/crimson/perks/ids.py:perk_display_name()/perk_display_description().
2. Sharpshooter (PerkId.SHARPSHOOTER)¶
Original¶
player_update(0x004136b0): forcesspread_heat = 0.02while active.player_fire_weapon(0x00444980): appliesshot_cooldown *= 1.05and avoids the normal post-shot spread heat increase.- Rendering: draws the laser overlay in the player render path.
Rewrite¶
- Shot cooldown and spread behavior:
src/crimson/gameplay.py:player_fire_weapon(),player_update(). - Laser rendering:
src/crimson/render/world_renderer.py:_draw_sharpshooter_laser_sight().
3. Fastloader (PerkId.FASTLOADER)¶
Original¶
player_start_reload(0x00413430): applies the multiplier when starting a reload.
Rewrite¶
src/crimson/gameplay.py:player_start_reload().
4. Lean Mean Exp. Machine (PerkId.LEAN_MEAN_EXP_MACHINE)¶
Original¶
perks_update_effects(0x00406b40): timer-based periodic XP grant.
Rewrite¶
src/crimson/perks/runtime/effects.py:perks_update_effects().- Lean Mean step:
src/crimson/perks/impl/lean_mean_exp_machine_effect.py:update_lean_mean_exp_machine().
5. Long Distance Runner (PerkId.LONG_DISTANCE_RUNNER)¶
Original¶
player_update(0x004136b0): move-speed ramp/decay logic with perk-enabled extension to 2.8.
Rewrite¶
src/crimson/gameplay.py:player_update().
6. Pyrokinetic (PerkId.PYROKINETIC)¶
Original¶
perks_update_effects(0x00406b40): selects an aim target viacreature_find_in_radius(..., 12.0, 0)and runs the timer/FX emission.
Rewrite¶
src/crimson/perks/runtime/effects.py:perks_update_effects().- Pyrokinetic step:
src/crimson/perks/impl/pyrokinetic_effect.py:update_pyrokinetic().
7. Instant Winner (PerkId.INSTANT_WINNER)¶
Original¶
perk_apply(0x004055e0): adds 2500 XP.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/instant_winner.py:apply_instant_winner().
8. Grim Deal (PerkId.GRIM_DEAL)¶
Original¶
perk_apply(0x004055e0):experience += int(experience * 0.18)thenhealth = -1.0.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/grim_deal.py:apply_grim_deal().
9. Alternate Weapon (PerkId.ALTERNATE_WEAPON)¶
Original¶
player_apply_move_with_spawn_avoidance(0x0041e290): movement scaling.player_update(0x004136b0): reload-triggered swap behavior + shot cooldown bump.perk_can_offer(0x0042fb10): mode-flag gating (flags & 0x2) prevents offers in two-player.
Rewrite¶
- Swap and carry behavior:
src/crimson/gameplay.py:player_swap_alt_weapon(),player_update(). - Bonus application during swap path:
src/crimson/bonuses/apply.py:bonus_apply(). - Offer gating:
src/crimson/perks/availability.py:perk_can_offer().
10. Plaguebearer (PerkId.PLAGUEBEARER)¶
Original¶
perk_apply(0x004055e0): setsplayer_plaguebearer_active(global-ish field on player0).creature_update_all(0x00426220): infection flagging, ticking, spread (plaguebearer_spread_infection), and infection kill bookkeeping.perk_can_offer(0x0042fb10): hardcore quest 2-10 special-case blocks Plaguebearer.
Rewrite¶
- Flag application:
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to: src/crimson/perks/impl/plaguebearer.py:apply_plaguebearer()(setsplaguebearer_activefor all players).- Creature-side behavior:
src/crimson/creatures/runtime.py:CreaturePool.update()(contact infection, tick damage, spread). - Offer gating:
src/crimson/perks/availability.py:perk_can_offer()hardcore quest gate.
11. Evil Eyes (PerkId.EVIL_EYES)¶
Original¶
perks_update_effects(0x00406b40): updatesevil_eyes_target_creatureviacreature_find_in_radius.creature_update_all(0x00426220): skips AI update for the targeted creature.
Rewrite¶
src/crimson/perks/runtime/effects.py:perks_update_effects().- Evil Eyes step:
src/crimson/perks/impl/evil_eyes_effect.py:update_evil_eyes_target(). - Freeze behavior:
src/crimson/creatures/runtime.py:CreaturePool.update()(evil-eyes target handling).
12. Ammo Maniac (PerkId.AMMO_MANIAC)¶
Original¶
perk_apply(0x004055e0): reassigns each player's current weapon to force clip recalculation.weapon_assign_player(0x00452d40): applies the clip-size modifier.
Rewrite¶
- Clip sizing:
src/crimson/gameplay.py:weapon_assign_player()(Ammo Maniac modifier). - Apply-time reassignment:
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to: src/crimson/perks/impl/ammo_maniac.py:apply_ammo_maniac().
13. Radioactive (PerkId.RADIOACTIVE)¶
Original¶
creature_update_all(0x00426220): proximity check, timer wrap, falloff damage; special-case kill/XP handling.- Rendering: draws the player aura (effect atlas id
0x10).
Rewrite¶
- Gameplay:
src/crimson/creatures/runtime.py:CreaturePool.update()(Radioactive tick and kill handling). - Rendering:
src/crimson/render/world_renderer.py: player aura in_draw_player_trooper_sprite().
14. Fastshot (PerkId.FASTSHOT)¶
Original¶
player_fire_weapon(0x00444980): applies the cooldown multiplier.
Rewrite¶
src/crimson/gameplay.py:player_fire_weapon().
15. Fatal Lottery (PerkId.FATAL_LOTTERY)¶
Original¶
perk_apply(0x004055e0):(crt_rand() & 1)decides XP vs death.perk_can_offer(0x0042fb10): mode-flag gating rejects the perk in quest mode and two-player.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/fatal_lottery.py:apply_fatal_lottery().- Offer gating:
src/crimson/perks/availability.py:perk_can_offer().
16. Random Weapon (PerkId.RANDOM_WEAPON)¶
Original¶
perk_apply(0x004055e0): random selection (weapon_pick_random_available) with up to 100 retries to avoid pistol/current, thenweapon_assign_playerwith the last roll.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/random_weapon.py:apply_random_weapon().
17. Mr. Melee (PerkId.MR_MELEE)¶
Original¶
creature_update_all(0x00426220): on contact-damage tick, callscreature_apply_damage(attacker, 25, damage_type=2, impulse=(0,0))when Mr. Melee is active, without suppressing the player damage path.
Rewrite¶
src/crimson/creatures/runtime.py:_creature_interaction_contact_damage()(Mr. Melee branch + deferred death handling).
18. Anxious Loader (PerkId.ANXIOUS_LOADER)¶
Original¶
player_update(0x004136b0): checksinput_primary_just_pressed()and applies the timer reduction.
Rewrite¶
src/crimson/gameplay.py:player_update().
19. Final Revenge (PerkId.FINAL_REVENGE)¶
Original¶
player_take_damage(0x00425e50): death check triggers the revenge burst and radial damage viacreature_apply_damage(damage type 3).perk_can_offer(0x0042fb10): mode-flag gating rejects the perk in quest mode and two-player.
Rewrite¶
- Death hook implementation:
src/crimson/perks/impl/final_revenge.py:apply_final_revenge_on_player_death(). - Hook wiring and death pipeline call-site:
src/crimson/sim/world_state.py. - Offer gating:
src/crimson/perks/availability.py:perk_can_offer().
20. Telekinetic (PerkId.TELEKINETIC)¶
Original¶
- Bonus update logic uses a per-player aim-hover timer and a fixed delay threshold.
Rewrite¶
src/crimson/bonuses/update.py:bonus_telekinetic_update().src/crimson/bonuses/pool.py:bonus_find_aim_hover_entry().
21. Perk Expert (PerkId.PERK_EXPERT)¶
Original¶
- Perk selection UI logic adjusts choice count and layout while the perk is active.
Rewrite¶
- Choice count:
src/crimson/perks/selection.py:perk_choice_count(). - UI layout + sponsor text:
src/crimson/ui/perk_menu.py,src/crimson/views/perks.py.
22. Unstoppable (PerkId.UNSTOPPABLE)¶
Original¶
player_take_damage(0x00425e50): gates the disruption logic on perk presence.
Rewrite¶
src/crimson/player_damage.py:player_take_damage().
23. Regression Bullets (PerkId.REGRESSION_BULLETS)¶
Original¶
player_fire_weapon(0x00444980): implements the "fire during reload by paying XP" path; this branch is gated byexperience > 0.player_start_reload(0x00413430): reload restart guard when Regression Bullets or Ammunition Within is active.
Rewrite¶
src/crimson/gameplay.py:player_fire_weapon()(reload firing + XP drain),player_start_reload()(restart guard).
24. Infernal Contract (PerkId.INFERNAL_CONTRACT)¶
Original¶
perk_apply(0x004055e0): applies the health reduction and perk/level grants.- Perk offering logic blocks the perk under Death Clock.
Rewrite¶
- Apply:
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to: src/crimson/perks/impl/infernal_contract.py:apply_infernal_contract().- Selection/gating:
src/crimson/perks/selection.py:perk_generate_choices().
25. Poison Bullets (PerkId.POISON_BULLETS)¶
Original¶
projectile_update(0x00420b90): sets weak poison on hit (flags |= 0x01) when(crt_rand() & 7) == 1.creature_update_all(0x00426220): applies self-damage usingcreature_apply_damage(..., damage_type=0, impulse=(0,0)).- Toxic Avenger does not modify this projectile-hit poison branch; strong poison (
flags |= 0x02) comes from Toxic Avenger melee retaliation increature_update_all. - Rendering: creature overlay draws aura
0x10when poison flag is set. perk_can_offer(0x0042fb10): hardcore quest 2-10 special-case blocks Poison Bullets.
Rewrite¶
- Poison flagging:
src/crimson/projectiles.py:ProjectilePool.update()hit logic. - Poison tick:
src/crimson/creatures/runtime.py:CreaturePool.update()routes self-damage throughcreature_apply_damage(). - Aura render:
src/crimson/render/world_renderer.py: creature overlay inWorldRenderer.draw(). - Offer gating:
src/crimson/perks/availability.py:perk_can_offer()hardcore quest gate.
26. Dodger (PerkId.DODGER)¶
Original¶
player_take_damage(0x00425e50): Dodger iscrt_rand() % 5 == 0if Ninja is not active.
Rewrite¶
src/crimson/player_damage.py:player_take_damage().
27. Bonus Magnet (PerkId.BONUS_MAGNET)¶
Original¶
- Bonus spawn-on-kill logic (
bonus_try_spawn_on_kill): additional roll gates on perk.
Rewrite¶
src/crimson/bonuses/pool.py:BonusPool.try_spawn_on_kill().
28. Uranium Filled Bullets (PerkId.URANIUM_FILLED_BULLETS)¶
Original¶
creature_apply_damage(0x004207c0): whendamage_type == 1, doubles damage.
Rewrite¶
src/crimson/creatures/damage.py:creature_apply_damage().
29. Doctor (PerkId.DOCTOR)¶
Original¶
creature_apply_damage(0x004207c0): bullet damage scaling.- Target selection: uses
creature_find_in_radius(aim, 12.0, 0). - HUD draw: draws a 64px bar with the clamped
health/max_healthratio.
Rewrite¶
- Damage:
src/crimson/creatures/damage.py:creature_apply_damage(). - UI:
src/crimson/modes/base_gameplay_mode.py:_draw_target_health_bar(), andsrc/crimson/ui/hud.py:draw_target_health_bar().
30. Monster Vision (PerkId.MONSTER_VISION)¶
Original¶
- Selection: no FX-detail offer gate in
perks_generate_choices; Monster Vision is part of the 25% rarity reject group. - Rendering: creature render pass draws
0x10behind creatures; shadow pass is disabled while active.
Rewrite¶
- Offer gating:
src/crimson/perks/availability.py:perk_can_offer(). - Perk selection:
src/crimson/perks/selection.py:perk_generate_choices(). - Rendering:
src/crimson/render/world_renderer.py:WorldRenderer.draw()(Monster Vision overlay and shadow gating).
31. Hot Tempered (PerkId.HOT_TEMPERED)¶
Original¶
player_update(0x004136b0): timer logic + randomized interval + ring spawn.
Rewrite¶
src/crimson/perks/impl/hot_tempered.py:tick_hot_tempered().
32. Bonus Economist (PerkId.BONUS_ECONOMIST)¶
Original¶
- Bonus application scales duration increments while the perk is active.
Rewrite¶
src/crimson/bonuses/apply.py:bonus_apply()(economist multiplier).
33. Thick Skinned (PerkId.THICK_SKINNED)¶
Original¶
perk_apply(0x004055e0): health scaling on pick.player_take_damage(0x00425e50): damage scaling.- Perk offering blocks it under Death Clock.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/thick_skinned.py:apply_thick_skinned().src/crimson/player_damage.py:player_take_damage().- Offer gating:
src/crimson/perks/selection.py:perk_generate_choices().
34. Barrel Greaser (PerkId.BARREL_GREASER)¶
Original¶
creature_apply_damage(0x004207c0): bullet damage scaling.projectile_update(0x00420b90): doubles the movement step count when the perk is active and the projectile is player-owned.
Rewrite¶
- Damage:
src/crimson/creatures/damage.py:creature_apply_damage(). - Projectile stepping:
src/crimson/projectiles.py:ProjectilePool.update().
35. Ammunition Within (PerkId.AMMUNITION_WITHIN)¶
Original¶
player_fire_weapon(0x00444980): implements the "fire during reload by paying health" path; this branch is also gated byexperience > 0.player_start_reload(0x00413430): restart guard.
Rewrite¶
src/crimson/gameplay.py:player_fire_weapon()andplayer_start_reload().
36. Veins of Poison (PerkId.VEINS_OF_POISON)¶
Original¶
creature_update_all(0x00426220): on contact-damage, checksshield_timerand sets poison flags.- Perk offering: hardcore quest gating.
Rewrite¶
- Contact poison flagging:
src/crimson/creatures/runtime.py:_creature_interaction_contact_damage(). - Offer gating:
src/crimson/perks/availability.py:perk_can_offer().
37. Toxic Avenger (PerkId.TOXIC_AVENGER)¶
Original¶
creature_update_all(0x00426220): sets both weak+strong poison flags.
Rewrite¶
src/crimson/creatures/runtime.py:_creature_interaction_contact_damage().
38. Regeneration (PerkId.REGENERATION)¶
Original¶
perks_update_effects(0x00406b40): heal loop.
Rewrite¶
src/crimson/perks/runtime/effects.py:perks_update_effects().- Regeneration step:
src/crimson/perks/impl/regeneration_effect.py:update_regeneration().
39. Pyromaniac (PerkId.PYROMANIAC)¶
Original¶
creature_apply_damage(0x004207c0): fire damage scaling and acrt_rand()side-effect.- Perk offering logic gates by current weapon.
Rewrite¶
- Damage:
src/crimson/creatures/damage.py:creature_apply_damage(). - Offer gating:
src/crimson/perks/selection.py: perk generation rules (perk_generate_choices()weapon gate).
40. Ninja (PerkId.NINJA)¶
Original¶
player_take_damage(0x00425e50): Ninja dodge check is evaluated before Dodger.
Rewrite¶
src/crimson/player_damage.py:player_take_damage().
41. Highlander (PerkId.HIGHLANDER)¶
Original¶
player_take_damage(0x00425e50): Highlander replacement behavior.perk_can_offer(0x0042fb10): mode-flag gating rejects Highlander in quest mode and two-player.perks_generate_choices(0x00430160): Death Clock active path rejects Highlander from offers.
Rewrite¶
src/crimson/player_damage.py:player_take_damage().- Offer gating:
src/crimson/perks/availability.py:perk_can_offer(), plus Death Clock block insrc/crimson/perks/selection.py:perk_generate_choices().
42. Jinxed (PerkId.JINXED)¶
Original¶
perks_update_effects(0x00406b40): manages the timer and both the self-damage and random-creature-death branches.
Rewrite¶
src/crimson/perks/runtime/effects.py:perks_update_effects().- Jinxed steps:
src/crimson/perks/impl/jinxed_effect.py:update_jinxed_timer(),update_jinxed().
43. Perk Master (PerkId.PERK_MASTER)¶
Original¶
- Perk selection UI logic increases the choice count.
Rewrite¶
src/crimson/perks/selection.py:perk_choice_count().
44. Reflex Boosted (PerkId.REFLEX_BOOSTED)¶
Original¶
- Main loop: when in gameplay state,
frame_dt *= 0.9while active.
Rewrite¶
src/crimson/sim/world_state.py:WorldState.step().
45. Greater Regeneration (PerkId.GREATER_REGENERATION)¶
Original¶
- No active tick/usage located in the authoritative decompile; only selection/apply bookkeeping references.
Rewrite¶
- Default rewrite mode: Greater Regeneration upgrades Regeneration heal ticks
from
+dtto+2*dt(same RNG gate inperks_update_effects). - With
--preserve-bugs: no runtime effect (matches original). - Implementation:
src/crimson/perks/impl/regeneration_effect.py:update_regeneration(). - Cleared by Death Clock apply:
src/crimson/perks/impl/death_clock.py:apply_death_clock().
46. Breathing Room (PerkId.BREATHING_ROOM)¶
Original¶
perk_apply(0x004055e0): applies health reduction, forces creature hitbox ramp, clears guard.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/breathing_room.py:apply_breathing_room().
47. Death Clock (PerkId.DEATH_CLOCK)¶
Original¶
perk_apply(0x004055e0): clears regen perks and sets health to 100.player_take_damage(0x00425e50): early-return immunity.projectile_update(0x00420b90): player-hit path directly subtracts fixed projectile damage (bypassesplayer_take_damage).perks_update_effects(0x00406b40): per-frame drain logic.bonus_pick_random_type(0x00412470): medikit suppression while active.- Perk offering: blocks multiple perks while active.
Rewrite¶
- Apply:
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to: src/crimson/perks/impl/death_clock.py:apply_death_clock().- Offer gating:
src/crimson/perks/selection.py:perk_generate_choices(). - Medikit suppression:
src/crimson/gameplay.py:bonus_pick_random_type(). - Damage immunity:
src/crimson/player_damage.py:player_take_damage(). - Projectile player-hit damage path:
src/crimson/player_damage.py:player_take_projectile_damage(), called fromsrc/crimson/projectiles.py:ProjectilePool.update(). src/crimson/perks/runtime/effects.py:perks_update_effects().- Death Clock step:
src/crimson/perks/impl/death_clock.py:update_death_clock().
48. My Favourite Weapon (PerkId.MY_FAVOURITE_WEAPON)¶
Original¶
perk_apply(0x004055e0): immediate +2 clip size.weapon_assign_player(0x00452d40): applies +2 on assignment.- Bonus selection/spawn logic removes weapon bonuses while active.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/my_favourite_weapon.py:apply_my_favourite_weapon().src/crimson/gameplay.py:weapon_assign_player(),bonus_pick_random_type().src/crimson/bonuses/pool.py:BonusPool.try_spawn_on_kill().src/crimson/bonuses/apply.py:bonus_apply().
49. Bandage (PerkId.BANDAGE)¶
Original¶
perk_apply(0x004055e0): random multiply + clamp + burst FX.
Rewrite¶
- Default rewrite mode: heals
+1..+50HP (clamped to 100), matching the in-game perk description text. - With
--preserve-bugs: keeps the native multiplier behavior (health *= 1..50). src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/bandage.py:apply_bandage().
50. Angry Reloader (PerkId.ANGRY_RELOADER)¶
Original¶
player_update(0x004136b0): half-threshold detection and ring spawn.
Rewrite¶
src/crimson/gameplay.py:player_update()reload perks section.
51. Ion Gun Master (PerkId.ION_GUN_MASTER)¶
Original¶
creature_apply_damage(0x004207c0): ion damage scaling (damage type 7).projectile_update(0x00420b90): ion AoE scale.
Rewrite¶
- Damage:
src/crimson/creatures/damage.py:creature_apply_damage(). - AoE radii:
src/crimson/projectiles.py: ion behavior scaling.
52. Stationary Reloader (PerkId.STATIONARY_RELOADER)¶
Original¶
player_update(0x004136b0): compares previous/current position to decidereload_scale = 3.0.
Rewrite¶
src/crimson/gameplay.py:player_update().
53. Man Bomb (PerkId.MAN_BOMB)¶
Original¶
player_update(0x004136b0): timer accumulation/reset and ring spawn logic.- Ordering detail:
player_man_bomb_timeris incremented/checked before the later movement gate clears it (player_state + 0x7c = 0) when position changed.
Rewrite¶
src/crimson/perks/impl/man_bomb.py:tick_man_bomb()mirrors native ordering (burst check first, movement reset after).- Movement/stationary state feed:
src/crimson/gameplay.py:player_update().
54. Fire Cough (PerkId.FIRE_CAUGH)¶
Original¶
player_update(0x004136b0): timer and interval rerolling.- Uses
projectile_spawn(..., PROJECTILE_TYPE_FIRE_BULLETS, owner_id)plusfx_spawn_sprite(...).
Rewrite¶
src/crimson/perks/impl/fire_cough.py:tick_fire_cough().- Player aim/input feed:
src/crimson/gameplay.py:player_update()(sprite FX viaGameplayState.sprite_effects).
55. Living Fortress (PerkId.LIVING_FORTRESS)¶
Original¶
player_update(0x004136b0): timer accumulation/reset.creature_apply_damage(0x004207c0): bullet damage scaling.
Rewrite¶
- Timer:
src/crimson/gameplay.py:player_update(). - Damage:
src/crimson/creatures/damage.py:creature_apply_damage().
56. Tough Reloader (PerkId.TOUGH_RELOADER)¶
Original¶
player_take_damage(0x00425e50): checksreload_activeand halves damage.
Rewrite¶
src/crimson/player_damage.py:player_take_damage().
57. Lifeline 50-50 (PerkId.LIFELINE_50_50)¶
Original¶
perk_apply(0x004055e0): direct deactivation in pool iteration order, plus burst FX.
Rewrite¶
src/crimson/perks/runtime/apply.py:perk_apply()dispatches to:src/crimson/perks/impl/lifeline_50_50.py:apply_lifeline_50_50().