Survival one-off weapon handouts¶
This page expands the survival_update (0x00407cd0) handout logic that grants
two non-quest weapons in Survival and is therefore a concrete lead for secret
weapon behavior.
Why this matters for secrets¶
- The handout code directly assigns:
- weapon id
24(0x18) — Shrinkifier 5k - weapon id
25(0x19) — Blade Gun - Both weapons are absent from
quest_unlock_weapon_idinquest_database_init; see weapon candidates. - The startup secret-hint block says there are "few secret weapons hidden inside the game"; these handouts are two verified runtime paths that fit that hint.
Handout A: time-based Shrinkifier 5k¶
survival_update runs the check when all of these are true:
- single-player (
config_player_count == 1) survival_reward_damage_seen == 0survival_reward_fire_seen == 0run_elapsed_ms > 64000survival_shrinkifier_handout_enabled != 0
Side effects:
- only if the current weapon is Pistol (
player_state_table[0].weapon_id == 1): weapon_assign_player(0, 24)survival_reward_weapon_guard_id = 24- always:
survival_shrinkifier_handout_enabled = 0survival_reward_damage_seen = 1survival_reward_fire_seen = 1
The flag writes sit outside the Pistol test, so reaching 64 seconds while holding another weapon consumes the chance without a grant.
Handout B: low-health centroid Blade Gun¶
survival_update grants id 25 if all of these are true:
- single-player (
config_player_count == 1) survival_first_kill_count == 3survival_reward_fire_seen == 0- player distance to centroid of first 3 recorded death positions is
< 16.0 player_health < 15.0- this check does not require
survival_shrinkifier_handout_enabled != 0and does not testsurvival_reward_damage_seen
Centroid formula:
cx = (p0.x + p1.x + p2.x) * 0.33333334cy = (p0.y + p1.y + p2.y) * 0.33333334
Side effects:
weapon_assign_player(0, 25)survival_reward_weapon_guard_id = 25survival_reward_fire_seen = 1survival_shrinkifier_handout_enabled = 0
Decoded Blade-hint mapping (inference)¶
From the decoded secret line in Easter eggs:
Dead Center Inside The Triangle Of The First Blood Sacrifice Yourself For Firepower
The Blade Gun handout gate matches this text closely:
- "Dead Center Inside The Triangle" -> player must stand near the centroid of
three recorded death positions (
distance < 16.0). - "Of The First Blood" -> the check uses the first three stored death samples
(
survival_first_kill_count == 3, positions at indices 0..2). - "Sacrifice Yourself" -> player health must be low (
player_health < 15.0). - "For Firepower" -> reward is weapon id
25(Blade Gun).
This mapping is an evidence-backed inference, not a direct static code xref from
the secret string to survival_update.
Gate writers and lifecycle¶
Related writes outside survival_update:
player_updatesetssurvival_reward_fire_seen = 1only after held fire or auto-fire passes the normal or reload-perk shot-readiness gate. Holding fire during cooldown does not set it.player_take_damagesetssurvival_reward_damage_seen = 1on damage attempts (including shielded hits).creature_handle_deathrecords up to 3 death positions and incrementssurvival_first_kill_countup to 6.- When
survival_first_kill_countreaches3,creature_handle_deathsets: survival_reward_fire_seen = 0survival_shrinkifier_handout_enabled = 0This is the key transition that enables the second handout check.
Run reset state (gameplay_reset_state) initializes:
survival_reward_weapon_guard_id = 1survival_first_kill_count = 0survival_reward_damage_seen = 0survival_reward_fire_seen = 0survival_shrinkifier_handout_enabled = 1
Temporary weapon guard behavior¶
gameplay_render_world enforces that ids 24 and 25 are only valid when the
guard id matches:
- if
player_weapon_id == 25andsurvival_reward_weapon_guard_id != 25, force Pistol (weapon_assign_player(..., 1)) - if
player_weapon_id == 24andsurvival_reward_weapon_guard_id != 24, force Pistol (weapon_assign_player(..., 1))
This makes the handouts effectively temporary, guard-bound rewards instead of normal unlocks.
Evidence pointers¶
- Recovered sources under
decomp/1.9/crimsonland/: game/survival_update.cpp(0x00407cd0): both handout checksgame/gameplay_render_world.cpp(0x00405960): guard checksgameplay/player_update_heading.cpp(player_update,0x004136b0): fire flag writecrimsonland/player_take_damage.cpp(0x00425e50): damage flag writecrimsonland/creature_handle_death.cpp(0x0041e910): recent-death trackinggameplay/gameplay_reset_state.cpp(0x00412dc0): run resetdocs/re/static/reference/weapon-id-map.mddocs/re/static/secrets/weapon-candidates.mddocs/crimsonland-exe/survival.md