T10 is an independent format using the shared limited-overs match engine. Existing teams can open their T10 squad and choose Copy T20 squad. This creates new player rows, preserves pool identity links and ratings, and starts career statistics at zero. It refuses to replace an existing T10 profile. Subsequent T10 ratings are independent; newly selected pool players seed from their T20 pool ratings, including user overrides and valid zero values.
This is the SimCricketX preset, based on published ECN allocation tables, not a claim of current league compliance. Rain targets retain the engine’s approximate D/L Standard Edition resource calculation; this is not the professional DLS implementation. Fielding restrictions affect probabilities, not positional placement. Timers, over-rate penalties, reviews and league-specific substitutions are outside scope.
Both halves of a T10 are meant to play alike: if the side batting first hits big, the chase hits big back, and wickets fall in the last three overs as the price of that hitting rather than as a collapse. That is a property of the engine, not of the scoring matrices, and it is gated in scripts/bench_t10.py:
The last two gates exist because the first five did not catch a real failure. Every earlier gate is an average or a ratio, and a second innings can satisfy all of them while still folding for 19 now and then. Every wicket multiplier in the engine is applied multiplicatively, and apart from the game-state engine’s own [0.35, 3.00] clamp nothing bounded their product — collapse risk, consecutive wickets, a fresh partnership, the required-aggression band, risk urgency, the pressure band and the aggressive game mode all stack on the same delivery. In a chase they share one trigger: wickets push the required rate up, which switches on the escalators, which take more wickets. A side a few down could reach a 0.68 chance of losing a wicket to the very next ball, and measured on real squads, 12 Green chases in 300 were bowled out inside five overs, the fastest in 17 deliveries. Two changes fix it, both applying to both innings so the parity above is preserved: SHORT_COLLAPSE_DAMPEN in game_state_engine keeps 40% of the collapse and consecutive-wicket escalation, so wickets still cluster without running away; and SHORT_FORMAT_WICKET_CAP in ball_outcome is a ceiling of 0.30 on the chance any single delivery is a wicket — a rare backstop rather than a routine clamp.
Everything that produces this is gated on FormatConfig.strict_short_bowling, so T20, List A and First-Class keep the behaviour their own bands were pinned on. The pieces are: one risk-to-reward mapping shared by both innings in PressureEngine.get_risk_based_effects (boundaries ×1.6 against wickets ×1.0, so aggression buys more runs than wickets); no calculate_defensive_factor and no first-innings rebuild, so neither half of a T10 has a brake and both play alike (bowlers_day no longer auto-triggers in any format — see the third REPIN NOTE in tests/test_scoring_calibration.py); an exactly neutral get_chasing_advantage; pitch-relative thresholds in both innings’ pressure scores in place of raw T20 run rates; wicket-cost damping in both required-aggression and run-rate-pressure bands in game_state_engine; softened boundary suppression in the collapse and consecutive-wicket layers; no new-batter caution during the death overs; and a toss modifier at a third of its full-length size, since which innings receives it is fixed by the pitch rather than by either captain’s call.
engine/format_catalog.py supplies public identities, scheduled lengths, labels and controls. engine/format_config.py supplies deep-copied per-match rules. engine/short_bowler_manager.py owns strict quotas and memoized completion feasibility. T10 uses its own block in config/ground_conditions_defaults.yaml; editing that block cannot alter legal phases or innings length. Rain rebuilds the effective rules used by selection, scoring and live responses.
The shared outcome model uses a four-ball settling period, twelve-delivery game-state window, partnership thresholds 15/30/45/60 and dot thresholds 2/3/5/6 for T10. Chase urgency is relative to the pitch’s expected scoring rate. _T10.par_scores, pitch_par_factors and rrr_baseline are all DERIVED from expected_rr (Powerplay 12.0, Middle 11.0, Death 15.0) and target_scores (Green 95, Dry 100, Hard 125, Flat 137, Dead 155), so those two must move whenever the scoring matrices do — otherwise every first innings reads as ahead of par and bats conservatively while every chase sits permanently above required-aggression 1.0. Pitch wear retains a physical delivery scale rather than doubling because an innings is shorter.
A test-only T5 preset exercises thirty legal balls and one-over quotas. T5 is not registered for users: production support needs explicitly chosen rules and its own tuning, rather than treating a reduced T20 or T10 game as a T5 competition.
Run .venv/bin/python -m pytest -o addopts='' tests/test_t10.py tests/test_t10_integration.py for T10 rules, rain recovery, squad isolation, setup, competitions, statistics and rendering contracts.
Run .venv/bin/python scripts/bench_t10.py --seeds 120 for reproducible calibration. It writes reports/t10_calibration.json with day/night innings totals, wickets, dots, boundaries, extras, per-phase and per-over scoring, and chase results. It enforces the first-innings bands (Green 88–105, Dry 92–110, Hard 116–136, Flat 128–148, Dead 145–168), at least 10% more Hard-pitch runs per legal ball than the same T20 fixture, and the innings-parity gates described below. These are engineering acceptance bands, not league-average claims.
The existing scheduled-overs migration must run before rollout. There are no T10-specific pool columns and no deployment-time bulk profile creation. Refresh can reuse a live limited-overs instance, and Super Over snapshots retain T10 and revised rain allocations. Durable recovery of ordinary innings after process loss remains outside this release.
The final 300-seed sample per pitch, run in both day and day/night conditions, covered 3,000 T10 matches, and every band and parity gate passed. Day first-innings means were Green 104.4, Dry 108.4, Hard 125.1, Flat 138.0 and Dead 156.8, on 4.89 / 4.60 / 3.66 / 3.32 / 1.58 wickets. Dot rates ran 30.8% down to 17.2% and boundaries per hundred balls 25.3 up to 42.9. Hard scoring per legal ball exceeded the same-seed T20 baseline by 32.9%.
Innings parity, second against first: runs per ball 1.008–1.021, wickets per ball 0.991–1.174, death-over wicket share within four points on every surface but Dry, chase win rates 53.7–64.0%. Fifth-percentile totals were 84/77 (Green), 86/69 (Dry), 105/100 (Hard), 113/113 (Flat) and 136/136 (Dead). The fastest an innings was bowled out: 29 balls on Green, 30 on Dry, 45 on Hard, 48 on Flat, never on Dead.
For comparison, before this work the same harness measured runs per ball 0.891–1.004, wickets per ball 1.27–1.88, a Green chase taking 21% of its wickets in the death overs against the first innings’ 43%, a Green chase scoring 70.0 against 84.9 — and, on Green, 12 chases in 300 bowled out inside five overs with the fastest taking 17 deliveries.
The T10 suites pass 60 tests, including nine pinning the invariants directly: no defensive shutdown, an exactly neutral chasing advantage, identical risk coefficients in both innings, no bowlers_day at seven down, the game-state flags, a new batter still swinging at the death, the derived par curve, the single-delivery wicket ceiling, and the damped collapse escalation. tests/test_reset_stale_t10_pitch_tuning.py covers the ground-config migration. T20, List A and First-Class calibration regressions are unmoved, and all 147 JavaScript tests pass.
The browser check scripts/check_t10_ui.cjs needs Playwright, which is not installed in every environment; it was not run for this pass.