DEV Situation Tester
⚠ Sandbox — changes here do NOT affect the public page
Backtest Year
Grading the 2023 season · everything dated 2023 or later is invisible to the model
Backtest Snapshots
— save full sandbox state (32 teams + settings), restore instantlyDEV Settings (Sandbox)
Changes here are isolated — they do NOT affect the live situation tester
Simulation Year (Back-Testing)
Set to a past year to shift retention bonuses — e.g. 2024 makes the 2024 draft class act as the "current" rookies, getting the 2026-class bonus tier. It also cuts every play-caller profile: only seasons before this year are read (the sim year itself only when it's that caller's sole season).
The tester header's Backtest Year panel sets the same value and shows what that year still needs.
Active: Sim Year 2023
Shift = 2026 − 2023 = +3 years
Draft 2023 → gets bonus of draft 2026
Deterministic RB Situation V2 (2023+)
Uses Dynamic Anchor + projected touches + role-aware competition + PFF rushing scheme + OL + pass role, followed by environment/goal-line/monopoly modifiers. Legacy RB categories remain in code and data but become dormant for migrated records.
Recommended: leave both ON. Complete players use V2; incomplete players use the preserved legacy safety path. Import status is visible in the new RB Annual Data tab. Turn dynamic anchor OFF to stop the years + career-touches regression so every high-OVR back (veterans included) reads his raw prospect grade.
Applies the Grade Range Bonuses table (grade range × draft year) to RB V2. The bonus lands on the dynamic anchor AFTER career regression — never before it, so a declining draft class is not regressed twice — and it is applied to every back in the room, so a marked-down veteran gives the pool back to his teammates and their touches / competition / OVRs move with him. The pct and its point value are always keyed off the player's own prospect grade range, exactly like every other position. Turn OFF to price RB V2 purely off the anchor + situation.
OFF (bit-for-bit legacy): a retention decline is subtracted from the anchor, so the whole floor–ceiling band slides down and an aging back loses the same points in a great situation as in a bad one. ON (default, floor_k 1.5): his outcome band is built from the pre-decline anchor; the decline R deepens the floor by floor_k × R and the ceiling keeps (ceil_k × R, default 0) — the situation percentile then decides how much of the decline is realized. At floor_k 2 the grade matches legacy where the effective percentile is 50% (situation ≈ 50 for anchors under 90); above that he declines less than legacy, below it more. Elite anchors (90+) carry the fill-resistance stretch, so their crossover sits higher — a −5 Henry (100) at k=2 reads 83 / 86 / 89 / 93 / 96 at situation 40 / 52 / 65 / 78 / 88 vs legacy 87 / 89 / 92 / 94 / 96; k≈1 matches legacy at the median for a 100 anchor. Positive retention (a bonus) always stays on the anchor, and the room still prices him off the declined anchor (touches / shares / RB2 multiplier unchanged) — only his own band changes shape. With the current −1% / −3% table the effect is ≤ 1 OVR; it matters once the decline side of the table is steepened.
Offense (w/o RB) — the ten-point slot: QB ×40% + weapons ×25% + pass scheme ×35%, then curved
Leave blank to follow the RB Off Score Low/High Thresh situation settings (falling back to 74 → 88) — the quality composite realistically lives in that band, whereas the old hardcoded 68 → 92 put 20 of 32 teams at ≤2.5/10, so good offenses read as if they were bad. The score is t^exp × max where t is the position inside the band, so it is continuous at both ends (the old normalised-exponential ramp jumped ~1.4 pts at the floor and pinned a league-average offense at 2.9/10). exp = 1 is linear and lands a mid-band offense at exactly half the points; raise it to concentrate points on elite offenses, lower it to compress the top. Weapons are read from the converged dynamic grades and empty wr3/te2 seats are dropped instead of injecting a phantom league-average 75.
RB V2 — Pool Accuracy (Fills, Usage Guide, Talent Power, Overlap Gate, Vet Protection, Dormant Upside)
2023-backtested pool-accuracy features (docs/rb-power-receiving-score-guide.md §5–§10). usage guide: imported PFF targets/YAC/RZ-targets stamp a recalibrated receiving score (prior tgt/g is the best predictor of next-year receiving share); multi-year imports blend with year drop-off (rec_decay per season back, rec_lookback max) and only seasons PRIOR to the simulation year are visible. parity fills: backs with no usage rows fill at league parity instead of anchor-scaled values (no more rookie-fill room flips). talent power: power channel = 25% size + 60% anchor + 15% broken-tackle rate (legacy keeps weight as 45% owner). overlap gate: PHI-style overlap rooms hand the receiving pool to the better back; complement rooms (a true power lead) never fire, and since 2026-09-07 neither do near-peer rooms — the lead must out-anchor the companion by rb_pool_overlap_min_anchor_gap (8; PHI 14.0 fires, PIT 4.4 stands down so Warren keeps his own receiving work; 0 = the old gate). reservation always: RB3+ backs took ≥5% of carries on all 32 teams in 2023 — reserve room for them even when no third back is carded. vet protection: rookie behind a clearly better vet keeps only part of his OVR standing (MIA 2023 fix). dormant upside: young high-anchor/low-usage receivers (2023 Gainwell) keep their low share but get a wider percentile upside band — the gate reads the multi-season PFF usage-guide receiving score first (DORMANT_USAGE_SCORE_V1) and only inverts the archetype multiplier when no PFF usage rows exist, so a college-table/parity-filled multiplier can no longer mask real low usage. Pair with rb_pool_receiving_exp 2 (RB V2 section below). receiving lane (RB_REC_LANE_V1): receiving becomes a SEPARATE OVR track — the OVR pool ranks overall talent only (scheme-fit blend off), the opportunity math splits into a carry pool (power+OVR × rb_opportunity_att) and a parallel receiving pool (receiving × rb_receiving_opportunity targets), clear-lead dominance stops damping the receiving pool (a 95% carrier can't zero the second back's passing-down work), and the receiving score earns an additive post-percentile boost: per_point × (recScore − threshold) × (100−OVR)/(100−ref), capped. The match bonus's receiving channel routes to the lane so the signal never double-counts. Docs: docs/rb-receiving-lane-overhaul.md.
RB V2 — Detached Receiving Pool (projTargets), Role Floor & Situation Weights
RB_VOLUME_WEIGHTED_V1 — the carries-only feed did not under-weight receptions, it excluded them: a third-down back projected for 48 catches fed 8 carries into the volume curve AND the RB2 multiplier (TEN Spears), while the receiving component that could have credited him is dormant at weight 0. weighted feeds carries + receptions × rec_weight (2.0 = the conservative standard-scoring end; PPR is nearer 4) without putting the double-counting additive sum back. Against the live carries feed, 23 of the 32 RB2s in the 2023 export change multiplier bucket (every back whose catches carry him over a 4.0 / 7.5 / 11.0 touches-per-game line); the 6%-catch power back (NO Williams) and the backs already in the top bucket do not. rec_weight 0 reproduces the carries feed bit-for-bit.
projTargets is the receiving side's own opportunity number, mirroring the carry side term for term: projTargets = teamBackfieldTargets × recShare, then projReceptions = projTargets × catchRate(receiving score) beside projCarries = (team_rush_att − qb_rush_att) × carryShare. The team-level pie is the OC profile's rb_rec_targets column (next to team_rush_att, backfilled from TeamGradeArchive.rb_receiving_targets); while a profile has none, the pool is estimated from pass volume with the rb_proj_targets_pass_att_*/share_of_pass constants below, or — if rb_proj_targets_fallback_ratio is used instead — as a share of the carry pool. Detaching means the receiving channel no longer counts inside the combined pool share that sizes touches: it is its own pool, and the rushing pool keeps the carry side. Nothing about the pool math itself changed — same rb_pool_receiving_exp, same spill, same specialist split and overlap gate.
Role floor — the depth chart as a FLOOR, not the determinant: RB1 is lifted toward rb_pool_role_floor (0.50) of the room's allocatable pool, no companion may exceed rb_pool_role_rb2_cap (0.60), and the pool still decides everything in between. A lead already above the floor is untouched BY CONSTRUCTION (the pass never lowers him), so TEN/LAR/KC/SF are left alone. rb_pool_role_floor_strength (0.70) is how much of the lead's deficit the lift closes: at 1.0 (the previous ship, with the floor at 0.45) every sub-floor room snapped onto the same 45.1 / 42.9 point and the grades that fed it were erased; at 0.70 a room that wanted 26% and one that wanted 46% still print different numbers. Tuned as a pair on the 2023 backtest (node analysis/role-floor-2023-backtest.mjs --grid): 0.50 × 0.70 → MAE 11.45 pp, bias −0.29, 10 of 10 fired rooms distinct, vs 11.76 / −0.91 / 2 of 6 before. 0.45 + 1.0 reproduces the previous ship bit-for-bit. The cap is inert in a two-back room at any floor ≥ 0.45 (45 + 55 = 100) — it exists for three-starter rooms. rb_pool_role_floor_vol_sens skews both bounds with the team's rushing volume (low volume → committee → softer floor; every-volume → steeper), floored at rb_pool_role_floor_min. rb_pool_role_floor_rec_pool additionally bounds the receiving pool (off by default — a designated RB2 receiver keeps his passing-down work). rb_situation_v2_rb2_mult_enabled OFF lets the floor stand alone instead of also discounting the RB2's volume. Docs: docs/rb-detached-rec-pool-proj-targets-role-floor.md.
Situation-score component weights — the totals are renormalized to 100, so editing these re-slices the same 100 points instead of inflating the scale (defaults = the historical maxes 35 / 25 / 15 / 15 / 10).
Raising weight_receiving above 0 turns projTargets into a scored situation component (a volume statement — targets per game ramped to full points), and every other component gives up its share of the 100 points proportionally. Keep rb_rec_lane_max_boost at 0 while it is non-zero if you do not want the same receiving channel also paid as the additive OVR lane boost.
RB V2 — Room Lock, Specialist Splits & Match Bonus
rb_pool_roster_lock (recommended ON): only backs named on the DEV roster enter the room — stale same-team rows (e.g. a departed free agent still stamped with last year's abbreviation) and blank-team rows can never leak into the pool. OFF = legacy fallback: unclaimed rows need a real matching team abbreviation. rb_pool_split_enabled: in a two-back rotation with a near-tied pool OVR and opposite archetypes, each back primarily dominates his own channel (receiving back takes the Receiving pool, power back takes Power / Goal Line) instead of the OVR spill blurring both. rb_pool_clear_lead_enabled: a back who beats the room on ALL THREE channel ratings (power + receiving + OVR pool by the min edges) keeps a decisive share instead of the soft committee split — the dominance boost fades out as his raw combined share approaches bellcow territory (fade_share) and the specialist split stands down for sweep rooms (a hierarchy is not a rotation).
rb_pool_clear_lead_max_edge_ratio (RB_CLEAR_LEAD_BALANCE_V1, default 3): a sweep only earns the dominance multiplier when it is BROAD — the largest of its three edges divided by the smallest must stay at or under this. Real bellcows beat the room roughly evenly (Conner-class ≈ 2.1); ATL 2023 was +2.3 power / +16.7 receiving / +11.3 OVR (ratio 7.3) — a receiving blowout dragging a rounding-width power edge over the gate, and it was boosted in all three lanes. An unbalanced sweep is still recognized (the specialist split stays suppressed: a back who is better everywhere is not in a rotation) but every pool keeps its own arithmetic. 0 = no balance test (the pre-balance rule, bit-for-bit). Raising rb_pool_clear_lead_min_edge instead does not work: ATL's smallest edge (2.3) equals the coin-flip guardrail's.
RB_MATCH_BONUS_V1 — perfect backfield match: up to rb_pool_match_bonus_max (+15% default) on the outcome percentile, scaling smoothly from the start thresholds to the full thresholds (no jump). A mid-band archetype (e.g. a 0.63 receiving multiplier is only ~55% up the 0.55→0.70 ramp) earns a partial bonus even at full team volume.
ELITE_FLOOR_CEIL_V2 — 100-OVR outcomes land lower and are harder to fill out: extra floor drop (a ~100 anchor bottoms out ≈ floor 100 − (10 + slope)), a soft ceiling cap that eases off at perfect outcomes (a perfect situation can still grade a true 100), and a percentile stretch above hard_start so only a near-perfect situation reaches the ceiling.
RB_SHARE_SCALED_FLOOR_V1 — backups with good anchors: the talent floor scales with projected pool share. shareFactor = clamp(0, 1, (start − poolShare) / span); maxDrop ×= (1 + drop_extra × shareFactor). Defaults 0.50 / 0.35 / 1 → a ≥50%-share bellcow is untouched, a ≤15%-share back's drop doubles (84 anchor: floor 68 → 53).
RB_SHARE_SCALED_CEIL_V1 — bellcows with modest anchors: the mirror of the share-scaled floor. The upside gain scales with projected pool share. gainShareFactor = clamp(0, 1, (poolShare − start) / span); maxGain ×= (1 + gain_extra × gainShareFactor). Defaults 0.55 / 0.30 / 1 → a ≤55%-share back is untouched, a ≥85%-share bellcow's gain doubles (76.6 anchor: ceiling 86 → 95). The soft elite cap still applies. gain_extra 0 turns it off.
Projected Passing Scheme (PROJ_SCHEME_V1)
When enabled, each team's passing_scheme_rating is replaced by a QB-independent projection derived from the team OC's residual + QB grade. Requires scheme archive data with QB grades and OC names.
Projected Volume (PROJ_VOL_V1)
When enabled, each team's passing/running volume rating is replaced by a projection from the OC's volume profile, shifted by the current RB room vs the OC's RB baseline, plus a game-script bump.
Projection Display (MEDIAN_TOGGLE_V1)
Show the Median projection column beside Low/High for EVERY position — in the Projected Rankings player panel and in the tester's Projected Season Stats card. Off = the classic Low/High pair. The rankings list still sorts by median pts/game either way, so ordering never changes.
RB Backfield Competition — Relative Gap Scales
Lower = steeper penalty per point of gap; higher = more forgiving. Power & OVR use OVR-point units; Receiving uses YPRR units.
RB Veteran Incumbency Resistance
A young back (year 1/2) fighting an established vet takes a pct deduction on Power/Receiving before the gap. Scales by vet prospect grade (floor→0, full→1). Fires when Me < 3 seasons AND the vet is at least min_gap seasons senior AND the young back's prospect grade is not talent_override pts above the vet. Applies to the less-experienced player on either side (mirror).
RB Backfield Comp — Pool Allocation
When ON, three sub-pools of 10 (Power, Receiving, OVR) are split by rating^E / Σ(ratings^E) across the full room (starters + qualifying bench RBs). Committee penalty emerges naturally. OFF = pairwise gap scoring (A/B vs anchors).
Volume-Gated Concentration (rush-attempt scaling of exponents)
Below vol_low carries, exponents scale UP (more concentration); above vol_high, scale DOWN (more committee). OVR exponent gets full sensitivity; Power/Receiving get role_sens fraction. factor interpolates linearly between the two endpoints.
RB_LANE_WEIGHT_V1 — V2 room opportunity split (normalized to 1). Shipped 0.20 power / 0.40 OVR / 0.40 receiving: the power lane only correlates ~+0.38 with real carry share, so it no longer sizes a third of the room. Under the receiving lane the carry pair renormalizes (power ÷ (power + OVR)). Legacy split: 0.30 / 0.35 / 0.35.
RB_REC_YRR_WEIGHT_V1 — college receiving composite (z-weights against the calibrated anchors; the √Σw² denominator normalizes them, so they need not sum to 1). Shipped 0.75 Y/RR / 0.10 MTF-rec / 0.15 breakaway: MTF rec is a raw CAREER COUNT (r ≈ +0.40 vs usage) and at its old 0.25 it outvoted Y/RR (r ≈ +0.58) — a high-volume college checkdown back out-scored a more efficient one. Legacy split: 0.60 / 0.25 / 0.15.
Sub-Pool Combination Weights (how Power/Receiving/OVR parts combine into competitionScore; 1/1/1 = equal)
RB_FULLSCORE_THRESH_V1 — gap over the other back for a FULL 10/10 (linear ramp through parity: gap 0 → 5/10). OFF by default — leaves exponent/volume/spillover tuning in control.
RB_ROLE_PROT_SETTINGS_V1 — young back (seasons ≤ max) behind 2-of-3 sub-scores vs a more experienced back loses OVR standing. Mult = fraction KEPT (0.82 → vet takes 18%).
Two-tier protection — vet is protected MORE when the young back grades better (strong = rb_role_protection_mult) than when he grades worse (weak). gap_floor stops protection once the young back is that many points BEHIND (set −22 to match the incumbent-share fit; −999 = no floor).
RB_VOLUME_DOMINANCE_V1 — a suppressed back who owns his backfield climbs back toward his prospect grade, capped there. climb = (prospect − grade) × ramp(best sub-pool axis, floor→ceil) × offenseWeakness × strength, then damped for elite prospects (damp_max at damp_full, none at/below damp_start).
RB Projection — Gap-Split Role Modifiers
When ON, the backfield archetype gap scores (Power/Receiving/OVR, 0–10, 5=parity) scale RB projections: rush yards, rec yards, receptions, and rush TDs. shareMult = 1 + (score−5)/5 × M. The two backs' scores mirror, so gains/losses are zero-sum across the room. When OFF, the legacy compMult handles role splits.
RB Total Yard Curve (RB_TOTAL_EXP_V1)
Single exponential replacing the old rb1/rb2 linear total-yard curves. projTotal = ceiling × exp(k × ((ovr + rb2_adj) − 100)). rb2_adj applies only to the rb2 slot.
Select a team to start testing


