What Beats What: Reading Coverage and Pass Concepts Versus Coverages

How a quarterback works out the coverage in the second after the snap, which pass concepts are built to beat which coverages, and why every ‘beater’ is a bet, not a guarantee.

Show the Python (shared drawing helpers for this chapter)
import os
import logging

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, FancyArrowPatch, RegularPolygon, Patch
from matplotlib.lines import Line2D
from matplotlib.colors import ListedColormap, BoundaryNorm, LinearSegmentedColormap, TwoSlopeNorm

from gridiron import Play, Player, style, draw_marker, show_animation, routes as r
from gridiron.play import MARKER_R

logging.getLogger("matplotlib.font_manager").setLevel(logging.ERROR)
style.apply()
PDF = os.environ.get("RTG_FORMAT", "").lower() in ("pdf", "typst", "print")

GREEN = "#0f7a55"          # darker step of the aqua highlight: text, the QB's eyes, open windows
OD, DD = style.OFFENSE_DARK, style.DEFENSE_DARK
LOS = 40                   # the offense's own 30: room for deep routes
SPLIT = 1.6                # center-to-guard and guard-to-tackle spacing, as in the rest of the book


# --------------------------------------------------------------- players and alignments
def O(key, pos, d, w, label=None):
    return Player(key, pos, "off", d, w, label=key if label is None else label)


def D(key, pos, d, w, label):
    return Player(key, pos, "def", d, w, label=label)


def line():
    """The five offensive linemen, 1.6 yards apart; only the center is lettered."""
    keys = ["LT", "LG", "C", "RG", "RT"]
    return [O(k, k, -0.7, (i - 2) * SPLIT, "C" if k == "C" else "") for i, k in enumerate(keys)]


def spread(rb_w=-1.6, **moves):
    """11 personnel, shotgun 2x2: X and Z on the line outside (seven on the line with the five
    linemen), H (left slot) and Y (a tight end flexed into the right slot) a step off it."""
    off = line() + [O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, rb_w, "R"),
                    O("X", "WR", -0.7, -15.0), O("H", "WR", -1.5, -9.0),
                    O("Y", "TE", -1.5, 9.0), O("Z", "WR", -0.7, 15.0)]
    return [p.moved(d=moves[p.key][0], w=moves[p.key][1]) if p.key in moves else p for p in off]


SHELLS = {
    # two-high: safeties 13 deep a few yards outside the hashes, corners 7 off with outside leverage
    "two": {"FS": (13.0, -8.0), "SS": (13.0, 8.0), "LCB": (7.0, -15.8), "RCB": (7.0, 15.8)},
    # Cover 2 look: squat corners 5 off, safeties a little wider
    "c2": {"FS": (13.0, -8.5), "SS": (13.0, 8.5), "LCB": (5.0, -16.3), "RCB": (5.0, 16.3)},
    # one-high: free safety in the middle, strong safety down over Y
    "one": {"FS": (13.5, 0.0), "SS": (7.0, 8.4), "LCB": (7.0, -15.8), "RCB": (7.0, 15.8), "NB": (5.0, -8.6)},
    # man-free: pressed corners, nickel tight on H, strong safety over Y, free safety deep
    "man": {"FS": (14.0, 0.0), "SS": (5.0, 8.6), "LCB": (1.2, -14.4), "RCB": (1.2, 14.4), "NB": (1.6, -8.4)},
}


def nickel(shell="two", **moves):
    """A 4-2-5 nickel against the 2x2: ends outside the tackles, a 1-technique and a 3-technique,
    Mike and Will at 4.5 yards, the nickel ($) over H; the secondary from SHELLS[shell].
    `moves` = {key: (d, w)} overrides any spot."""
    base = {"LDE": (1.0, -5.5), "LDT": (1.0, -0.7), "RDT": (1.0, 2.35), "RDE": (1.0, 5.5),
            "WILL": (4.5, -2.6), "MIKE": (4.5, 1.8), "NB": (5.0, -8.6)}
    base.update(SHELLS[shell])
    base.update(moves)
    lab = {"LDE": ("DE", "E"), "LDT": ("DT", "T"), "RDT": ("DT", "T"), "RDE": ("DE", "E"),
           "WILL": ("WILL", "W"), "MIKE": ("MIKE", "M"), "NB": ("NB", "$"), "LCB": ("CB", "CB"),
           "RCB": ("CB", "CB"), "FS": ("FS", "FS"), "SS": ("SS", "SS")}
    return [D(k, lab[k][0], *base[k], lab[k][1]) for k in lab]


def keep(players, lo, hi):
    """Only the players whose width is inside (lo, hi): half-field plates leave the rest out, because
    gridiron draws a marker even when it falls outside a zoomed window."""
    return [q for q in players if lo <= q.w <= hi]


# --------------------------------------------------------------- scripting movement
def timed(p, key, way, kind="path"):
    """Script a player: `way` = [(t, d, w), ...] absolute spots reached at time t (s after the snap).
    Standing still between two times is allowed. (gridiron's actions are speed-based; this turns
    a timetable into them.)"""
    cur = np.array(p._cur(key), dtype=float)
    tc, wait = 0.0, 0.0
    for t, d, w in way:
        nxt = np.array([d, w], dtype=float)
        dist = float(np.hypot(*(nxt - cur)))
        if dist < 1e-3:
            wait += t - tc
        else:
            p._add(kind, key, [tuple(cur), tuple(nxt)], speed=dist / (t - tc), delay=wait)
            wait = 0.0
            cur = nxt
        tc = t
    return p


def route_to(p, key, *pts, speed=None, delay=0.0):
    """A route through absolute (d, w) points."""
    return p.route(key, list(pts), absolute=True, speed=speed, delay=delay)


def protect(p, t=0.7):
    """Five linemen set, four rushers engage them: enough to show it is a pass, no more."""
    for k, w in zip(["LT", "LG", "C", "RG", "RT"], (-3.9, -1.7, 0.0, 1.7, 3.9)):
        if k in p.players:
            timed(p, k, [(t, -1.7, w)], "block")
    for k, (d, w) in {"LDE": (-1.4, -4.7), "LDT": (-0.6, -1.0), "RDT": (-0.6, 2.0), "RDE": (-1.4, 4.7)}.items():
        if k in p.players:
            timed(p, k, [(t, d, w)], "rush")


def presnap(p):
    """gridiron starts the clock at the first pre-snap movement: a tiny Mike shuffle gives the play
    pre-snap frames to draw, while nobody else moves."""
    m = p.players["MIKE"]
    p.motion("MIKE", to=(m.d, m.w - 0.2), speed=0.12)


# --------------------------------------------------------------- drawing helpers
def _P(fld, p, d, w):
    return fld.xy(*p.to_abs(d, w))


def no_numbers(ax):
    """Remove the painted yard-line numbers (they sit where receivers and safeties stand)."""
    for t in list(ax.texts):
        if t.get_alpha() == 0.55:
            t.remove()


def say(fld, p, d, w, text, color=style.INK_2, fontsize=7.0, ha="center", weight="normal", box=True):
    """A short on-field label at (d, w)."""
    x, y = _P(fld, p, d, w)
    fld.ax.text(float(x), float(y), text, fontsize=fontsize, color=color, ha=ha, va="center", zorder=12,
                fontweight=weight,
                bbox=dict(boxstyle="round,pad=0.18", fc=style.SURFACE, ec="none", alpha=0.92) if box else None)


def point_to(fld, p, text_at, target, text, color=style.INK_2, fontsize=6.8, shrink=7, ha="center"):
    """A label with a thin leader line to the player or spot it names."""
    (xt, yt), (xp, yp) = _P(fld, p, *text_at), _P(fld, p, *target)
    fld.ax.annotate(text, (float(xp), float(yp)), xytext=(float(xt), float(yt)), fontsize=fontsize,
                    color=color, ha=ha, va="center", zorder=12,
                    arrowprops=dict(arrowstyle="-", color=color, lw=0.7, shrinkA=2, shrinkB=shrink),
                    bbox=dict(boxstyle="round,pad=0.18", fc=style.SURFACE, ec="none", alpha=0.92))


def opening(fld, p, center, size, color=style.THIRD, alpha=0.22):
    """A green patch: the window the throw goes into. size = (depth, width) in yards."""
    cx, cy = _P(fld, p, *center)
    fld.ax.add_patch(Ellipse((float(cx), float(cy)), size[1], size[0], fc=color, alpha=alpha, ec=color,
                             lw=0.9, ls=(0, (2, 1.5)), zorder=2.2))


def num(fld, p, n, at, color=GREEN, fs=7.4):
    """A progression number in a small circle."""
    x, y = _P(fld, p, *at)
    fld.ax.text(float(x), float(y), str(n), fontsize=fs, color="white", ha="center", va="center", zorder=13,
                fontweight="bold", bbox=dict(boxstyle="circle,pad=0.18", fc=color, ec="none"))


def ruler(fld, p, fs=6.0, top=30):
    """Depth labels (yards past the line of scrimmage) down the left edge of the window."""
    W = 160 / 3
    x_left = W - fld.y1 + 0.35
    for d in range(5, top + 1, 5):
        y = p.los + d
        if fld.x0 + 0.8 <= y <= fld.x1 - 0.8:
            fld.ax.text(x_left, y, f"{d}" + (" yd" if d == 5 else ""), fontsize=fs, color=style.INK_2,
                        ha="left", va="center", zorder=12,
                        bbox=dict(boxstyle="round,pad=0.12", fc=style.SURFACE, ec="none", alpha=0.85))


def eyes(fld, p, frm, to, frac=0.62, color=GREEN, label="eyes", fs=5.6, label_off=(1.4, 0.0)):
    """A dotted arrow from the quarterback toward where he is looking (gridiron's read line runs
    player to player; this one can point at an area)."""
    a, b = np.array(frm, float), np.array(to, float)
    tip = a + (b - a) * frac
    (x0, y0), (x1, y1) = _P(fld, p, a[0] + 0.9, a[1]), _P(fld, p, *tip)
    fld.ax.annotate("", (float(x1), float(y1)), xytext=(float(x0), float(y0)), zorder=8,
                    arrowprops=dict(arrowstyle="-|>", color=color, lw=1.3, ls=(0, (1, 1.4))))
    if label:
        say(fld, p, tip[0] + label_off[0], tip[1] + label_off[1], label, color=color, fontsize=fs)


def ghost_marker(ax, x, y, label, ppy, color=style.DEFENSE):
    """A hollow, dashed defender: where he stood before the snap."""
    ax.add_patch(RegularPolygon((x, y), 4, radius=MARKER_R * 1.25, orientation=np.pi / 4,
                                facecolor="none", edgecolor=color, lw=1.1, ls=(0, (2, 1.2)), zorder=6))
    if label:
        ax.text(x, y, label, ha="center", va="center", color=color, fontweight="bold", zorder=6,
                fontsize=max(4.0, min(8.0, ppy * 0.7)))


def draw(p, ax=None, lateral=(-21, 21), window=(-8.0, 24.0), width_in=6.5, rule=True, legend=False):
    """A static plate: the Play's own diagram, without the painted numbers, with a depth ruler."""
    fld = p.draw(ax=ax, lateral=lateral, window=window, width_in=width_in, title=False, legend=legend)
    no_numbers(fld.ax)
    if rule:
        ruler(fld, p)
    return fld


# --------------------------------------------------------------- frame strips for print
def snapshot(play, t, ax=None, ghosts=(), ghost_t=0.0, lateral=(-21, 21), window=(-9.0, 21.0),
             width_in=6.5, notes=(), look=None, look_off=(1.4, 0.0), look_label="eyes", opens=(), trail_from=None):
    """Everyone where he is at time t, with faint trails, hollow markers where `ghosts` stood at
    `ghost_t`, an optional QB eye-line `look`=(d, w), green windows `opens` [(center, size)] and
    `notes` [(text, (d, w)) or (text, (d, w), (d, w) of the player it names)]."""
    pos = {k: play.position(k, t) for k in play.players}
    moved = [pl.moved(d=float(pos[k][0]), w=float(pos[k][1])) for k, pl in play.players.items()]
    q = Play([m for m in moved if m.side == "off"], [m for m in moved if m.side == "def"],
             los=play.los, ball_y=play.ball_y, to_go=play.to_go)
    q.highlights = dict(play.highlights)
    fld = q.draw(ax=ax, lateral=lateral, window=window, width_in=width_in, title=False)
    ax, ppy = fld.ax, fld.pts_per_yard()
    no_numbers(ax)
    P = lambda d, w: fld.xy(*play.to_abs(d, w))  # noqa: E731
    for c, s in opens:
        opening(fld, play, c, s)
    start = trail_from if trail_from is not None else play._compile()[1]
    for k, pl in play.players.items():
        if pl.side == "off" and pl.pos in ("LT", "LG", "C", "RG", "RT"):
            continue
        pts = np.array([play.position(k, tt) for tt in np.linspace(start, t, 30)])
        if np.ptp(pts[:, 0]) + np.ptp(pts[:, 1]) < 0.3:
            continue
        xs, ys = P(pts[:, 0], pts[:, 1])
        if pl.side == "off":
            ax.plot(xs, ys, color=style.OFFENSE, lw=0.9, alpha=0.45, zorder=3)
        else:
            ax.plot(xs, ys, color=style.DEFENSE, lw=1.1, ls=(0, (3, 2)), zorder=3)
    if t > ghost_t + 0.05:
        for k in ghosts:
            x0, y0 = P(*play.position(k, ghost_t))
            ghost_marker(ax, float(x0), float(y0), play.players[k].label, ppy)
    if look is not None:
        eyes(fld, play, play.position("QB", t), look, label=look_label, label_off=look_off)
    bx, by = P(*play.ball_position(t))
    thrown = False
    for kind, _, t_rel in play.ball_events:
        if kind == "pass" and t > t_rel:
            thrown = True
            sx, sy = P(*play.ball_position(t_rel))
            ax.add_patch(FancyArrowPatch((float(sx), float(sy)), (float(bx), float(by)), arrowstyle="-|>",
                                         mutation_scale=8, color=style.BALL, lw=1.3, ls=(0, (2, 1.5)), zorder=9))
    if thrown or t <= 0:          # in the quarterback's hands the ball would hide his label
        draw_marker(ax, float(bx), float(by), "ball", "", ppy)
    for note in notes:
        text, (d, w) = note[0], note[1]
        x, y = P(d, w)
        box = dict(boxstyle="round,pad=0.2", fc=style.SURFACE, ec=style.BASELINE, lw=0.5)
        if len(note) > 2:
            xp, yp = P(*note[2])
            ax.annotate(text, (float(xp), float(yp)), xytext=(float(x), float(y)), fontsize=5.8, color=style.INK,
                        ha="center", va="center", zorder=13, bbox=box,
                        arrowprops=dict(arrowstyle="-", color=style.INK_2, lw=0.7, shrinkA=1, shrinkB=5))
        else:
            ax.text(float(x), float(y), text, fontsize=5.8, color=style.INK, ha="center", va="center", zorder=13,
                    bbox=box)
    return fld


STRIP_KEY = [Patch(facecolor="none", edgecolor=style.DEFENSE, lw=1.1, ls=(0, (2, 1.2)),
                   label="Dashed outline: where he stood before the snap"),
             Line2D([], [], color=GREEN, lw=1.3, ls=(0, (1, 1.4)), label="The quarterback's eyes"),
             Line2D([], [], color=style.DEFENSE, lw=1.1, ls=(0, (3, 2)), label="Defender's path so far"),
             Line2D([], [], color=style.OFFENSE, lw=1.0, alpha=0.6, label="Offensive player's path so far"),
             Line2D([], [], color=style.BALL, lw=1.3, ls=(0, (2, 1.5)), label="The pass"),
             Patch(facecolor=style.THIRD, alpha=0.3, edgecolor=style.THIRD, label="The window the ball goes to")]


def strip(play, times, labels, per_panel=None, ncols=2, width_in=6.5, lateral=(-21, 21), window=(-9.0, 21.0),
          legend=STRIP_KEY, **kw):
    """The print version of an animation: panels at chosen moments of one simulated play.
    `per_panel` = {i: dict(notes=..., look=..., opens=...)}."""
    n = len(times)
    nrows = int(np.ceil(n / ncols))
    pw = width_in / ncols
    h = nrows * (pw * (window[1] - window[0]) / abs(lateral[1] - lateral[0]) + 0.34)
    fig, axes = plt.subplots(nrows, ncols, figsize=(width_in, h), squeeze=False)
    for ax in axes.flat[n:]:
        ax.axis("off")
    for i, (ax, t, lab) in enumerate(zip(axes.flat, times, labels)):
        extra = (per_panel or {}).get(i, {})
        snapshot(play, t, ax=ax, lateral=lateral, window=window, **kw, **extra)
        ax.set_title(lab, fontsize=8.0, color=style.INK, loc="left")
    fig.tight_layout(h_pad=0.6, w_pad=0.4)
    if legend:
        fig.legend(handles=legend, loc="upper center", bbox_to_anchor=(0.5, 0.0), ncol=2, fontsize=7.2,
                   frameon=False)
    return fig


def animation_or_strip(play, times, labels, web_times=None, **kw):
    """A video on the website; the numbered frame strip in print."""
    if PDF:
        strip(play, times, labels, **kw)
        plt.show()
    else:
        show_animation(play, times=web_times or times)
Show the Python (the charting data behind this chapter’s numbers: nflverse via nflreadpy)
from gridiron.data import nfl, pbp

# 1. Targeted route x coverage, 2018-2022: one charting source (Next Gen Stats) for both labels
SEAS = [2018, 2019, 2020, 2021, 2022]
_part = nfl().load_participation(SEAS).to_pandas()[["nflverse_game_id", "play_id", "route", "defense_coverage_type"]]
_pl = pbp(SEAS, columns=["game_id", "play_id", "season_type", "pass_attempt", "sack", "success", "epa",
                         "receiver_player_id"])
_pl = _pl[(_pl["season_type"] == "REG") & (_pl["pass_attempt"] == 1) & (_pl["sack"] == 0)
          & _pl["receiver_player_id"].notna()]
TG = _pl.merge(_part, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
TG = TG[(TG["route"].fillna("") != "") & TG["defense_coverage_type"].notna()]
ROUTES = ["HITCH", "OUT", "SLANT", "CROSS", "IN", "CORNER", "POST", "GO"]
COVS = ["COVER_0", "COVER_1", "2_MAN", "COVER_2", "COVER_3", "COVER_4", "COVER_6"]
SUB = TG[TG["route"].isin(ROUTES) & TG["defense_coverage_type"].isin(COVS)]
SR = SUB.pivot_table(index="route", columns="defense_coverage_type", values="success", aggfunc="mean").loc[ROUTES, COVS]
NN = SUB.pivot_table(index="route", columns="defense_coverage_type", values="success", aggfunc="size").loc[ROUTES, COVS]
SR_MEAN = SUB["success"].mean()
OK = SR.where(NN >= 100)
SR_LO, SR_HI = OK.min().min(), OK.max().max()
ROWM = SUB.groupby("route")["success"].mean()           # each route's own average
RNG = (OK.max(axis=1) - OK.min(axis=1))                  # best minus worst coverage, per route
pts = lambda x: f"{100 * x:.0f}"      # noqa: E731
pc = lambda x: f"{100 * x:.0f}%"      # noqa: E731
N_TG = len(SUB)

# 1b. How often each coverage was played: share of charted dropbacks, same seasons and source
_db = pbp(SEAS, columns=["game_id", "play_id", "season_type", "qb_dropback", "down", "ydstogo"])
_db = _db[(_db["season_type"] == "REG") & (_db["qb_dropback"] == 1)]
_cv = _db.merge(_part[["nflverse_game_id", "play_id", "defense_coverage_type"]],
                left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
_cv = _cv[_cv["defense_coverage_type"].isin(COVS)]
COVSH = _cv["defense_coverage_type"].value_counts(normalize=True)
_long3 = _cv[(_cv["down"] == 3) & (_cv["ydstogo"] >= 7)]
MAN2_LONG3 = (_long3["defense_coverage_type"] == "2_MAN").mean()

# 2. Quarterbacks against two-high coverage, 2025 regular season (FTN-charted participation)
_p25 = nfl().load_participation([2025]).to_pandas()[["nflverse_game_id", "play_id", "defense_coverage_type"]]
_d25 = pbp([2025], columns=["game_id", "play_id", "season_type", "qb_dropback", "epa", "passer_player_name",
                           "first_down"])
_d25 = _d25[(_d25["season_type"] == "REG") & (_d25["qb_dropback"] == 1)]
QB = _d25.merge(_p25, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
QB = QB[QB["defense_coverage_type"].notna() & ~QB["defense_coverage_type"].isin(["BLOWN", "COMBO"])]
QB["two"] = QB["defense_coverage_type"].isin(["COVER_2", "2_MAN", "COVER_4", "COVER_6"])
_g = QB[QB["two"]].groupby("passer_player_name")["epa"].agg(["size", "mean"])
_g = _g[_g["size"] >= 150].sort_values("mean", ascending=False)
TWO_LG = QB.loc[QB["two"], "epa"].mean()
STAF = _g.loc["M.Stafford"]
STAF_RANK = int((_g["mean"] > STAF["mean"]).sum() + 1)
N_QB = len(_g)
FD_TWO = QB.loc[QB["two"], "first_down"].mean()                                   # FTN labels, 2025
FD_ONE = QB.loc[QB["defense_coverage_type"].isin(["COVER_1", "COVER_3"]), "first_down"].mean()
ORD = lambda n: {1: "the", 2: "second", 3: "third", 4: "fourth", 5: "fifth"}.get(n, f"{n}th")      # noqa: E731

Third-and-7, early in the second quarter. Before the snap the broadcast’s high camera shows two safeties, one on each side of the field, about 13 yards deep. The quarterback takes the snap, drops, and stares at the left side of the field, shoulders turned that way, as if he is about to throw the seam route over there. The right-hand safety, who reads the quarterback, takes two steps toward the middle to help. Then the quarterback turns his head, resets his feet and throws to the right: a 16-yard completion to a receiver standing all alone in the space that safety had been guarding. On the replay the analyst circles the safety and says, admiringly, “he looked him off.” A few plays later the same analyst says something else you have heard a hundred times: “That’s a great call against that coverage.” What does it mean for a play to be “great against” a coverage? How does the quarterback know, in the second and a half he has, which coverage it is? And if offenses know which plays beat which coverages, why doesn’t every pass work? This chapter puts the two halves of the book you have read so far, the pass concepts of Part 4 and the coverages of Part 6, on the same field.

You’ll be able to…

NoteYou’ll need

This chapter joins Parts 4 and 6. One line each:

NoteReading the diagrams

Offense is blue circles: X and Z the outside receivers, H the slot, Y a tight end flexed out like a second slot, Q the quarterback, R the back, C the center. Defense is outlined orange squares: E and T the linemen, M the Mike and W the Will linebacker, $ the nickel (slot cornerback), CB the cornerbacks, FS and SS the free and strong safety. Solid blue arrows are routes. Dashed orange arrows are zone drops; solid orange arrows are a defender carrying a receiver or rushing; dotted orange lines are man assignments; the dashed brown arrow is the pass. A green ring marks the defender to watch, a dotted green arrow is the quarterback’s eyes, and the green patch is the window the ball goes to. Small numbers on the left edge are yards past the line of scrimmage (the darker blue line); the orange line is the line to gain. Left and right are the offense’s.

The question under every pass

Every pass play starts with a question the quarterback has to answer faster than any other decision in sport: what coverage is this? Not because coaches love labels, but because the coverage decides where the empty grass will be. Cover 2 leaves the sideline between its squatting corner and its deep safety; Cover 3 leaves the flats and the seams; quarters leaves the space behind its read safeties’ eyes; man leaves whoever loses his one-on-one. Know the coverage and you know, roughly, where the ball should go before the receivers have finished their first steps.

Quarterback Play showed the quarterback’s clock: a drop timed to the depth of the routes, a progression run one look at a time, a key defender answering each look. It left one thing out on purpose, because Part 6 had not yet taught the coverages: how he decides which defender is the key, and which side to look at first. That is the coverage read. Coaches teach it in many dialects, but nearly all of them reduce to four steps, in order.

  1. Shell, before the snap. First, though, the protection: how many defenders could rush, and who is his hot receiver if one more comes than he can block (Pass Protection). Then the coverage: one deep safety or two? Corners pressed or off? Is anyone creeping? Which side is the field side (the wide side of the field, away from the hash the ball sits on), since many defenses set their rotation and their coverage by it? This produces a hypothesis: “two-high, corners squatting, probably Cover 2.”
  2. Rotation, at the snap. Did the safeties stay where they were, or did one spin to the middle and the other come down? Is the middle of the field open or closed? Did anyone extra rush? This confirms or overturns the hypothesis.
  3. Key defender, after the snap. Given the coverage, which single defender decides whether the called concept works? For smash against Cover 2 it is the cornerback; for flood the curl-flat defender; for dagger the safety and then the linebacker; for four verticals the deep middle safety.
  4. Throw. Read that defender and throw where he isn’t. If the answer is “nowhere,” move to the next read, and eventually to the checkdown.

Here are all four in one play, from the quarterback’s side.

Show the Python
def read_play():
    p = Play(spread(), nickel("c2", MIKE=(4.5, 4.4)), los=LOS, to_go=6)
    presnap(p)
    protect(p)
    p.dropback(2.5)
    # smash to the right: Z hitch settling at 7 (sticks + 1), Y corner route; the left side holds the free safety
    timed(p, "Z", [(0.95, 7.4, 15.0), (1.3, 6.8, 14.6)], "route")
    timed(p, "Y", [(1.35, 10.0, 9.4), (2.4, 16.5, 16.5), (2.9, 19.0, 18.5)], "route")
    timed(p, "X", [(2.9, 20.0, -15.5)], "route")
    timed(p, "H", [(2.9, 19.0, -8.2)], "route")
    timed(p, "RB", [(0.6, -4.2, -3.4), (1.4, -1.0, -7.0), (2.0, 0.2, -9.0)], "route")
    # the rotation: two-high becomes Cover 3, the strong safety skying down to the hitch side
    timed(p, "FS", [(1.0, 15.0, -3.0), (2.0, 17.0, -0.8), (2.9, 18.0, 0.0)], "drop")
    timed(p, "SS", [(0.8, 11.5, 10.0), (1.6, 10.0, 11.6), (2.6, 8.8, 12.4)], "drop")
    timed(p, "RCB", [(1.0, 8.5, 16.5), (1.8, 13.5, 16.6), (2.4, 16.5, 16.6), (2.9, 18.0, 17.0)], "drop")
    timed(p, "LCB", [(1.8, 13.0, -16.4), (2.9, 18.0, -16.8)], "drop")
    timed(p, "NB", [(1.4, 8.0, -11.5)], "drop")
    timed(p, "WILL", [(1.4, 8.5, -4.0)], "drop")
    timed(p, "MIKE", [(1.4, 8.5, 5.0)], "drop")
    p.pass_to("Z", t=1.4)
    p.highlight("FS", "SS", "RCB")
    return p


rp = read_play()
RT = [-1.0, 0.6, 1.4, 2.55]
animation_or_strip(rp, RT, ["1.  −1.0 s · Shell: two-high. Guess: Cover 2",
                            "2.  +0.6 s · Rotation: the middle closes",
                            "3.  +1.4 s · New key, the SS: still inside. Throw",
                            "4.  +2.55 s · Caught under the corner"],
                   ghosts=("FS", "SS", "RCB"), ghost_t=-1.0, window=(-9.0, 22.0),
                   per_panel={0: dict(look=(13.0, 16.0), notes=[("smash right:\nhitch + corner", (17.5, 11.0))]),
                              1: dict(notes=[("FS to the\nmiddle", (19.0, -6.0)), ("SS comes down", (16.0, 11.5))]),
                              2: dict(look=(14.3, 15.3), look_off=(-1.2, -2.6),
                                      notes=[("CB bails\nwith Y", (19.0, 11.0))]),
                              3: dict(opens=[((6.8, 15.2), (4.0, 5.0))],
                                      notes=[("deep third\ntaken", (19.5, 10.5))])})
Figure 42.1: How the quarterback reads coverage, in four moments of one simulated play (a frame strip; a video on the web). Third-and-6, and the call is smash to the right: Z runs a hitch that settles at 7 yards, past the line to gain, and Y a corner route over him. Panel 1, before the snap: two safeties 13 yards deep (ringed) and squatting corners 5 yards off. The hypothesis is Cover 2, so the quarterback’s eyes start on the right corner, the Cover 2 key, expecting him to squat on the hitch and give up the corner route. Panel 2, 0.6 seconds after the snap: the free safety (FS) has turned for the deep middle and the strong safety (SS) is coming down toward the flat on the smash side (a sky rotation: the strong safety down, the free safety to the middle). The middle has closed: this is Cover 3, and the hypothesis is dead. Panel 3, the key changes: the right corner, now a deep-third defender, bails with Y’s corner route, as every Cover 3 corner does, so watching him tells the quarterback nothing. The decision passes to the strong safety, who is now the curl-flat defender on that side. He is still working out from the middle, inside the hitch, so the ball comes out at 1.4 seconds as Z turns. Panel 4: Z catches it under the bailing corner, with the strong safety about three yards away and arriving after the ball. The dashed outlines show where the safeties and the right corner stood before the snap.

Notice what the quarterback did not do. He did not decide where to throw before the snap and then throw there; that is how the rotation in Disguise, Rotation, and Split-Field Coverage produced its interception. He also did not wait to see a receiver come open, which would have been too late: Z’s hitch is only open for the half-second before the strong safety arrives. He let one defender make the decision for him. Against Cover 2 that would have been the corner; once the coverage rotated to Cover 3, it became the strong safety rolling down to the flat. Either way the concept was built so that whatever that defender did, one of the two routes would be on the wrong side of him.

That is also why smash survived the rotation. Smash is built first of all to beat Cover 2, but its hitch sits under a Cover 3 corner who must bail and outside a flat defender who has to come from the middle of the field to reach it. The quarterback didn’t need to change the play. He needed only to know which half of it the coverage had handed him, and which defender now held the answer. (Had the strong safety sprinted straight to the hitch, the hitch would have been dead, and the throw would have been the corner route in the hole between him and the bailing corner, or nothing at all on this side.)

Step 1: the shell, and what it is worth

The pre-snap read is worth more than its reputation suggests, even in an era of disguise. First, it narrows the menu. A defense showing two deep safeties and two off corners is very unlikely to be in Cover 0 one second later; a defense showing one safety in the middle and pressed corners is unlikely to end up in quarters. Each shell makes some coverages easy to reach and others a long run away, and as Disguise, Rotation, and Split-Field Coverage showed, every defender has to stand where his real job is still reachable. Second, the shell sets up everything that has to be decided before the ball moves: the protection, which side the progression starts on, whether to take a shot (the alert, later in this chapter) and whether to change the play. How much the quarterback may change varies by team. In most NFL offenses the play-caller chooses the concept, and the quarterback’s freedom at the line is to flip it to the other side, to pick between two plays called together, or, in a check-with-me system, to choose from a short menu the coaches built for that week.

What the shell can’t do is name the coverage. The quarterback treats it as a short list ranked by likelihood: “two-high: Cover 2, quarters or 2-Man, unless they rotate.” The rest of the read decides between them.

Step 2: rotation, and the one-second answer

The single most useful question after the snap is the one you can ask from your couch: one second after the snap, how many safeties are deep in the middle of the field? One, and the middle is closed: Cover 1 or Cover 3 (or a fire zone, which is Cover 3 behind a blitz). Two, splitting the field, and it is open: Cover 2, Tampa 2, 2-Man, quarters or Cover 6. None: Cover 0, and the ball should already be on its way. Then the corners separate the members of each family: in the closed family, corners who turn and run with their receivers mean Cover 1 and corners who bail with their eyes on the quarterback mean Cover 3; in the open family, corners who squat in the flats mean Cover 2 (or the Cover 2 side of Cover 6), corners who backpedal and read mean quarters, and corners who trail their man mean 2-Man.

The quarterback answers that question with his first glance after the snap, often while he is still dropping. He does not need to see every defender. He needs the two safeties, because they are the ones a disguise moves, and the corner on the side he is reading. He can see them over linemen who are taller than he is because the safeties stand 10 to 15 yards deep, far above the line of helmets, and because from the shotgun he starts 5 yards behind the line with his eyes already up the field, instead of turning his back on the defense to drop from under center.

Against split-field coverage, Cover 6 for example (quarters on one half, Cover 2 on the other), “the” coverage doesn’t exist. The quarterback reads each half as its own coverage and works the half his concept is on: smash to the Cover 2 side, dagger or a quick out by #2 to the quarters side. Offenses that expect split-field coverage often call a different concept to each side and let the quarterback pick a half from the safeties’ alignment before the snap, which is the “man side, zone side” idea later in this chapter applied to two zones.

Step 3: the key defender for each coverage

Once the coverage has a name, the key defender follows from the concept and the coverage together. The table pairs each coverage with the defender quarterbacks are usually taught to read against it and where the ball tends to go. It is a summary of Part 6 from the offense’s side.

Table 42.1: The quarterback’s key against each coverage family. Typical, not universal: staffs teach different keys for the same coverage, and the concept called changes which defender matters.
Coverage (one second after the snap) Middle of the field The defender to read Where the ball usually goes
Cover 0 no deep safety the free rusher, if any (the hot read) the hot throw; a quick man-beater; any one-on-one deep if the protection holds
Cover 1 closed the matchup, and the robber if there is one the receiver who beats his man; crossers and rubs; away from the robber
Cover 3 closed the curl-flat defender (for smash and hitches too: the corner always bails); the post safety for seams the flat or the curl behind him; the seams; the hitch under a bailing corner; flood
Cover 3 match closed the seam-flat defender (did he carry #2?) the flat he left; post-wheel; the checkdown
Cover 2 open the corner (sideline); the safeties (middle) the corner route over the squat corner; the hole shot; the deep middle between the safeties
Tampa 2 open, Mike running the middle the Mike (which seam did he carry?) the other seam; the hole shot; the curl windows
2-Man open the trailing underneath defenders out-breaking routes away from their inside leverage; the back; a quarterback scramble
Quarters open the read safety (what did #2 do?) behind the safety once #2 takes him deep (dagger, scissors); quick outs to #2
Cover 6 open each half on its own: the corner on the Cover 2 side, the read safety on the quarters side smash to the Cover 2 half; dagger or a quick out by #2 to the quarters half
Fire zone closed the dropper and the seam-flat defenders the seams; the window behind the dropper; never the hot throw he is standing in

The key is almost always one of three kinds of defender: the conflict defender the concept was built against (the corner in smash, the curl-flat defender in flood), the safety who reads the quarterback (the post safety against four verticals, the robber against in-cuts), or, against man, the matchup itself, the receiver’s defender, read by his leverage and the help behind him.

Moving a defender with your eyes: the look-off

Every defender in the second category has a weakness built into his job. A post safety, a robber, a Tampa 2 Mike and most zone linebackers are taught to watch the quarterback, because the quarterback’s eyes and shoulders tell them where the ball is going before it leaves his hand. That makes them movable.

A look-off is the quarterback deliberately looking at one receiver or area, often turning his shoulders that way too, to pull a defender who reads his eyes toward it, and then throwing somewhere else, into the space that defender left. It is the quarterback’s half of the disguise contest: the defense lies with its alignment before the snap; the quarterback lies with his head after it.

Show the Python
def lookoff_play():
    dfn = nickel("man", SS=(9.5, 1.0), WILL=(4.0, 6.5), MIKE=(4.5, -1.0))
    p = Play(spread(rb_w=1.6), dfn, los=LOS, to_go=9)
    presnap(p)
    protect(p)
    timed(p, "RB", [(0.7, -4.6, 3.0)], "block")
    p.dropback(3.0)
    # Z: dig from the right at 12; H: a flat in-cut from the left at 11; X and Y run vertical
    timed(p, "Z", [(1.6, 12.0, 15.0), (2.4, 12.5, 10.0), (3.0, 12.5, 6.5)], "route")
    timed(p, "H", [(1.45, 9.5, -9.2), (2.2, 10.6, -5.6), (2.95, 10.8, -3.2)], "route")
    timed(p, "X", [(3.0, 19.0, -15.6)], "route")
    timed(p, "Y", [(0.8, 5.0, 10.5), (3.0, 18.5, 11.5)], "route")
    # man defenders trail their receivers
    timed(p, "RCB", [(1.6, 11.0, 15.6), (2.4, 11.2, 12.0), (3.0, 11.0, 9.0)], "path")
    timed(p, "NB", [(1.45, 8.6, -9.9), (2.2, 9.4, -7.6), (2.95, 9.8, -5.8)], "path")
    timed(p, "LCB", [(3.0, 17.8, -16.2)], "path")
    timed(p, "WILL", [(0.8, 4.6, 9.0), (3.0, 16.0, 9.6)], "path")
    timed(p, "MIKE", [(0.7, 2.5, 1.2), (1.5, 3.0, 2.4)], "path")      # the back blocks: the Mike sits
    # the robber follows the quarterback's eyes to the right, then has to come back
    timed(p, "SS", [(0.6, 10.0, 2.0), (1.5, 11.0, 4.6), (1.95, 11.3, 5.4), (2.95, 11.0, 2.2)], "drop")
    timed(p, "FS", [(1.5, 15.5, 1.2), (3.0, 17.5, 2.0)], "drop")
    p.pass_to("H", t=1.95)
    p.highlight("SS")
    return p


lp = lookoff_play()
LT = [0.0, 1.5, 1.95, 3.0]
animation_or_strip(lp, LT, ["1.  Snap · Cover 1, the SS in the hole as robber",
                            "2.  +1.5 s · Eyes right on Z's dig: the robber follows",
                            "3.  +1.95 s · Eyes snap left: throw to H",
                            "4.  +3.0 s · Caught where the robber was"],
                   ghosts=("SS",), ghost_t=0.0, window=(-9.0, 21.0),
                   per_panel={0: dict(notes=[("robber", (13.0, -2.5), (9.5, 1.0))]),
                              1: dict(look=(12.0, 12.5), notes=[("robber drifts\nwith the eyes", (16.5, 9.5))]),
                              2: dict(look=(10.5, -5.0)),
                              3: dict(opens=[((10.8, -3.0), (3.6, 5.0))],
                                      notes=[("too late", (15.5, 4.5), (11.0, 2.4))])})
Figure 42.2: A look-off against Cover 1 robber, simulated. Panel 1: man coverage, with the corners pressed, the nickel ($) on H, the Will on Y and the Mike on the back, one deep safety, and the strong safety (SS, ringed) sitting in the hole as a robber, free to jump any in-breaking route. The back stays in to block, so the Mike, who has him in man, has nobody to cover: he sits at the line, ready to rush late (the ‘hug’ of Blitz and Man Pressure). Panel 2, 1.5 seconds after the snap: the quarterback’s eyes and shoulders are on Z’s dig coming in from the right, and the robber, who reads the quarterback, has drifted with them. Panel 3: the eyes snap back to the left and the ball comes out to H, breaking flat across the field on his in-cut, with the nickel trailing him from outside. Panel 4: H catches it at 11 yards in the space the robber left; the robber, coming back, is about five yards short, and the nickel is still a step and a half behind. The dashed outline shows where the robber started.

Why does the robber bite? Because his job is to be right about in-breaking throws, and the best evidence he has is the quarterback. A robber who ignores the quarterback’s eyes and simply sits in the middle is easy to throw around; one who reads them gets interceptions. The look-off turns his best evidence into bad evidence. The same logic works on the deep middle safety against four verticals (Cover 3 drew it: the quarterback looks at one seam, the safety leans, the ball goes to the other) and on a Tampa 2 Mike deciding which seam to carry. The play in this chapter’s opening is the two-high version. A read safety in quarters or Cover 2 also helps toward wherever the quarterback is looking, so eyes on the left seam pull the right-hand safety a step inside, and the throw goes to the right, into the space he left. The robber is drawn here because with only one eye-reader on the field the mechanism is easiest to see.

What a look-off costs. Time, mostly. Holding a defender with your eyes takes a beat, perhaps three to five tenths of a second, and every beat is one more for the pass rush. So the look-off is usually built into the play’s timing rather than added to it: the first read of a progression doubles as the look-off for the second, as in the figure, where the quarterback had a real reason to look at Z’s dig before coming back to H. It also takes a quarterback who can reset his feet and throw accurately to the other side of the field without a wasted step. A look-off by a quarterback whose feet don’t follow his eyes is just a late throw.

The defense’s answer. Coaches teach the eye-readers to “read through” the quarterback: to take their cue from his shoulders and the way his feet are pointing rather than his helmet, because a quarterback can turn his head cheaply but has to set his feet to throw. Defenses also mix in defenders who don’t read the quarterback, such as a robber who reads a receiver instead, so a look-off aimed at the wrong defender moves nobody. And they disguise who the eye-reader is. A quarterback who looks off a safety who wasn’t reading him has wasted his beat.

NoteMadden vs. real life

In a video game, defenders mostly react to the ball and to their assignments, and where your quarterback’s helmet points is rarely part of the contest. On a real field it is one of the most important things he does. NFL coaches grade a quarterback’s eyes on film the way they grade his footwork, and the most-praised quarterbacks are the ones whose eyes move defenders. A quarterback who stares at his first read is said to be “staring down” the receiver, and safeties feast on it.

Watching a look-off from the couch

The look-off is one of the few post-snap skills you can see on a broadcast without the All-22 film. Watch the quarterback’s helmet, not the ball. If his head goes to one side and the ball comes out to the other, ask who moved while his head was turned. On the replay from behind the offense, find the safety or linebacker who took a step toward where the quarterback looked. That step is what the look-off bought.

What beats what: the matrix

Now the question the chapter’s title promises. A coverage beater is a pass concept whose routes are arranged to attack the known weak spots of a particular coverage, so that if the defense plays that coverage, at least one receiver should come open. Smash against Cover 2 is the textbook case. The phrase is used loosely on broadcasts, often with a confidence the football doesn’t support, so here is a tighter version: a beater raises the odds against its coverage. It doesn’t guarantee anything, and it is usually worse against other coverages. That trade is the subject of the next section; first, the map.

Don’t memorise the grid below; learn to rebuild it. Every cell follows from two questions you already know how to ask. Where are this coverage’s thin spots? (Part 6.) Which defender does this concept put in a bind, and does this coverage give that defender help? (Part 4.) Read across a row to see where a concept lives and dies: smash is great against Cover 2 and bad against 2-Man; four verticals destroys spot-drop Cover 3 and runs into a wall against 2-Man and Cover 3 match. Read down a column to see a coverage’s menu of problems: quarters suffers against dagger and scissors, man coverage against mesh. After the grid, this section walks the columns one coverage family at a time, with a picture for each.

Two limits of the grid are worth knowing before you use it. It grades dropback concepts against coverages, so it leaves out the two things that most often change a column. Play-action shifts every column a little toward the offense, because a run fake pulls the eye-reading linebackers and safeties forward, out of the windows behind them; that is why yankee, the one play-action row, grades so well against single-high coverage. And an RPO sidesteps the grid altogether by reading one defender’s run-or-pass reaction rather than the coverage (Run-Pass Options). The grid also doesn’t grade the run, which is where most of the coverages that look weak in it earn their keep, as the end of this section shows.

Show the Python
MCOVS = ["Cover 0", "Cover 1", "2-Man", "Cover 2", "Cover 3", "Cover 3\nmatch", "Quarters", "Cover 6", "Fire\nzone"]
GRADES = {   # +2 strong edge to the offense ... -2 strong edge to the defense (typical, not measured)
    #                                  C0  C1  2M  C2  C3  C3m  Q  FZ      (Cover 6 is computed below)
    "Quick game (stick, slant-flat)": [+1, 0, 0, 0, +1, 0, +1, 0],
    "Smash":                          [0, -1, -2, +2, +1, 0, 0, 0],
    "Flood (sail)":                   [-1, -1, -1, +1, +2, 0, +1, +1],
    "Levels / drive":                 [+1, +1, 0, +1, +1, 0, -1, 0],
    "Dagger":                         [-1, 0, -1, +1, 0, 0, +2, -1],
    "Y-cross":                        [-1, +1, 0, 0, +2, +1, 0, -1],
    "Mesh":                           [+2, +2, +1, 0, 0, 0, 0, -1],
    "Four verticals":                 [0, 0, -2, +1, +2, -1, -1, +1],
    "Post-wheel":                     [0, +1, -1, 0, +1, +2, +1, 0],
    "Scissors":                       [-1, 0, -1, +1, 0, 0, +2, -1],
    "Yankee (play-action shot)":      [0, +1, -1, -1, +2, +1, -1, -1],
    "Screens":                        [+1, 0, 0, -1, 0, 0, 0, +2],
}
# Cover 6 = quarters on one half, Cover 2 on the other: the mean of those two grades, rounded toward 0
for k, g in GRADES.items():
    g.insert(7, int(np.trunc((g[3] + g[6]) / 2)))
G = np.array(list(GRADES.values()))
MCOL = [style.DEFENSE, "#f6b89c", "#efeeea", "#9ec5f4", style.OFFENSE]
fig, ax = plt.subplots(figsize=(6.5, 5.0))
ax.imshow(G, cmap=ListedColormap(MCOL), norm=BoundaryNorm([-2.5, -1.5, -0.5, 0.5, 1.5, 2.5], 5), aspect="auto")
SYM = {2: "++", 1: "+", 0: "·", -1: "−", -2: "−−"}
for i in range(G.shape[0]):
    for j in range(G.shape[1]):
        v = G[i, j]
        ax.text(j, i, SYM[v], ha="center", va="center", fontsize=9 if v else 10, fontweight="bold",
                color="white" if abs(v) == 2 else style.INK)
ax.set_xticks(range(len(MCOVS)), MCOVS, fontsize=7.6)
ax.set_yticks(range(len(GRADES)), list(GRADES), fontsize=8)
ax.xaxis.tick_top()
ax.tick_params(length=0, labelcolor=style.INK)
ax.set_xticks(np.arange(-0.5, len(MCOVS)), minor=True)
ax.set_yticks(np.arange(-0.5, len(GRADES)), minor=True)
ax.grid(which="minor", color=style.SURFACE, lw=2)
ax.grid(which="major", visible=False)
for s in ax.spines.values():
    s.set_visible(False)
for x0, x1, txt in ((-0.45, 2.45, "man"), (2.55, 7.45, "zone"), (7.55, 8.45, "pressure")):
    ax.annotate("", (x0, -1.75), xytext=(x1, -1.75), annotation_clip=False,
                arrowprops=dict(arrowstyle="-", color=style.INK_2, lw=0.8))
    ax.text((x0 + x1) / 2, -1.95, txt, ha="center", va="bottom", fontsize=7.6, color=style.INK_2, style="italic")
handles = [Patch(fc=c, ec="none", label=l) for c, l in zip(MCOL[::-1], ["++ offense favoured", "+ edge offense",
                                                                        "· even / depends", "− edge defense",
                                                                        "−− defense favoured"])]
fig.legend(handles=handles, loc="lower center", ncol=5, fontsize=6.8, frameon=False, bbox_to_anchor=(0.5, -0.01))
fig.tight_layout(rect=(0, 0.04, 1, 1))
plt.show()
Figure 42.3: The concept-by-coverage matrix: the book’s summary, cell by cell, of which side a concept usually favours against each coverage when both are run as drawn. Blue is an edge for the offense, orange an edge for the defense, grey even or ‘depends’. These are typical grades from coaching wisdom and the reasoning of Parts 4 and 6, not measured values (the data chart later in the chapter shows how small measured edges are). The Cover 6 column is a blend of its two halves, the Cover 2 grade and the quarters grade averaged, with half-steps rounded toward grey, because the quarterback has to find the half his concept is on.

Against Cover 2: attack the sideline and the middle

Cover 2 has two deep defenders and five underneath, and its corners squat. That gives it two permanent thin spots: the sideline strip between the squatting corner and the deep-half safety, 12 to 20 yards deep, and the deep middle between the two safeties. Smash attacks the first, four verticals and dagger the second.

Show the Python
p = Play(spread(), nickel("c2", WILL=(4.5, -4.2), NB=(4.5, 6.6), MIKE=(4.5, 1.2)), los=LOS, to_go=8)
protect(p)
p.dropback(2.5)
p.route("Z", r.hitch(6.0))
route_to(p, "Y", (10.5, 9.2), (18.0, 20.0))
p.route("X", r.hitch(6.0))
route_to(p, "H", (10.5, -9.2), (18.0, -20.0))
route_to(p, "RB", (-4.6, -4.5), (-3.6, -11.5))
p.drop("RCB", (6.0, 18.2)); p.drop("LCB", (6.0, -18.2))
p.drop("SS", (17.5, 14.5)); p.drop("FS", (17.5, -14.5))
p.drop("NB", (8.5, 8.0)); p.drop("MIKE", (9.0, 0.5)); p.drop("WILL", (8.5, -8.0))
p.highlight("RCB")
p.pass_to("Y", t=1.9)
fld = draw(p, lateral=(-23.5, 23.5), window=(-8.0, 23.5))
opening(fld, p, (16.5, 18.0), (4.6, 5.6))
num(fld, p, 1, (19.6, 21.0)); num(fld, p, 2, (6.6, 13.3)); num(fld, p, 3, (-5.4, -11.8))
point_to(fld, p, (21.8, 5.0), (17.0, 17.0), "corner route lands behind\nthe CB, ahead of the late SS", color=GREEN)
say(fld, p, 3.0, 20.6, "CB squats\non the hitch", color=DD, fontsize=6.6)
say(fld, p, 21.6, -14.0, "mirror smash:\npick a side", color=OD, fontsize=6.6)
plt.show()
Figure 42.4: Smash against Cover 2 (a recap of the animation in Cover 2 and Tampa 2), run to both sides so the quarterback can pick one before the snap. On the right, Z runs a hitch at 6 yards and Y a corner route over him. The ringed corner, a Cover 2 hard corner, squats on the hitch, as his rules tell him to. The strong safety (SS) has the deep half behind him and does widen toward the corner route as it breaks, but he started 13 yards deep and 8 yards inside, near the hash, so he arrives late and the ball lands in the gap between the two (green). Progression, high to low: (1) the corner route if the corner sits, (2) the hitch if he sinks, (3) the back as the checkdown.

The reasoning is the one Cover 2 and Tampa 2 built move by move: the corner’s rule (squat on anything short in the flat) and the safety’s rule (stay deeper than anything in your half) are both sound, and smash places one route on each side of the line between them. The corner can’t be under the hitch and over the corner route at once, and the safety, starting near the hash, is a long way from the sideline. Flood earns a “+” here for the same reason, one step weaker: its sail route lands in the same hole, but its third route, in the flat, is exactly what the squatting corner is waiting for, so the defense covers one of flood’s three levels for free.

Four verticals attacks the other thin spot. With both seams running straight up the middle third of the field, each deep-half safety has a seam inside him and a go route outside him, and he can’t honour both; a quarterback who reads one safety throws to whichever receiver that safety doesn’t take. Tampa 2 exists to fix exactly this (the Mike runs down the middle and carries one seam), which is why four verticals is only a “+” against Cover 2 in the matrix: the Tampa version takes away one of the throws. NFL versions also build a choice into each seam (a route conversion): against two deep safeties the seam runners bend away from the safeties or split them, and against one they stay straight, which is part of why the concept survives a disguised coverage. The hole shot, a go route caught along the sideline behind the squatting corner, is the outside version of the same attack.

Against Cover 2 the offense gives up two things: the quick game to the outside, because the corners are sitting on it, and the screen, because the corner is also the force player and is standing right where a screen to the outside wants to go. Hence the grey and orange in those cells.

Against Cover 3: three under the deep ones, four across the front

Cover 3 is the opposite shape: three deep and four underneath. Its weaknesses, taught in Cover 3, are horizontal and vertical at once. Four underneath defenders can’t cover five short zones across the field, so the flats are thin; three deep defenders can’t cover four vertical routes, so the seams are thin. Flood attacks the first, four verticals the second.

Show the Python
def flood_play():
    dfn = nickel("one", NB=(5.0, 8.6), SS=(6.0, -8.8))
    p = Play(spread(rb_w=1.6), dfn, los=LOS, to_go=10)
    presnap(p)
    protect(p)
    p.dropback(2.5)
    timed(p, "Z", [(3.2, 21.0, 15.8)], "route")                                      # go: clears the corner
    timed(p, "Y", [(1.4, 9.5, 9.6), (2.1, 12.5, 14.5), (2.7, 13.5, 18.0), (3.4, 13.2, 18.6)], "route")  # sail
    timed(p, "RB", [(0.5, -3.8, 4.4), (1.3, 0.2, 10.0), (2.1, 1.6, 15.5), (2.7, 2.0, 18.0), (3.4, 2.2, 19.4)],
          "route")                                                                    # flat
    timed(p, "X", [(1.6, 12.0, -15.0), (2.1, 10.6, -14.0)], "route")                # curl
    timed(p, "H", [(2.7, 17.0, -7.6)], "route")                                     # seam: holds the FS
    timed(p, "RCB", [(1.0, 11.0, 16.2), (2.0, 17.5, 16.6), (2.8, 19.5, 16.6), (3.5, 18.0, 17.3)], "drop")
    timed(p, "NB", [(0.8, 7.5, 10.4), (1.5, 7.5, 13.2), (2.1, 6.0, 15.4), (2.7, 4.6, 16.8), (3.4, 6.5, 18.0)],
          "drop")
    timed(p, "MIKE", [(1.4, 8.5, 4.6), (2.7, 9.5, 7.6)], "drop")
    timed(p, "WILL", [(1.4, 8.5, -4.5)], "drop")
    timed(p, "SS", [(1.4, 8.5, -12.0), (2.1, 9.5, -13.0)], "drop")
    timed(p, "FS", [(1.4, 16.0, 0.0), (2.7, 17.5, 1.5)], "drop")
    timed(p, "LCB", [(1.4, 14.0, -16.0), (2.7, 17.0, -16.0)], "drop")
    p.pass_to("Y", t=2.0)
    p.highlight("NB")
    return p


fp = flood_play()
z1, y1, r1 = (fp.position(k, 1.0) for k in ("Z", "Y", "RB"))
animation_or_strip(fp, [0.0, 1.0, 2.0, 3.55],
                   ["1.  Snap · Cover 3: three deep, four under",
                    "2.  +1.0 s · Z clears the corner, Y stems",
                    "3.  +2.0 s · $ widens to the flat: throw the sail",
                    "4.  +3.55 s · Caught between $ and the corner"],
                   ghosts=("NB",), ghost_t=0.0, lateral=(-19, 22.5), window=(-8.0, 24.0),
                   per_panel={0: dict(notes=[("curl-flat\ndefender", (12.0, 11.5), (5.0, 8.6))]),
                              1: dict(notes=[("go", (12.5, 19.5), tuple(z1)), ("sail", (12.5, 6.0), tuple(y1)),
                                             ("flat", (-5.0, 10.0), tuple(r1))]),
                              2: dict(look=(20.0, 18.0), look_off=(-1.6, -2.2)),
                              3: dict(opens=[((13.2, 18.2), (4.0, 4.6))],
                                      notes=[("sail: 13 yd", (16.5, 11.0), (13.5, 17.6))])})
Figure 42.5: Flood against Cover 3, simulated (a frame strip; a video on the web). Panel 1: one deep safety, corners off, and the nickel ($, ringed) as the right curl-flat defender, the conflict defender for a flood to the right. Panel 2: Z’s go route carries the corner deep, because a Cover 3 corner may never let anyone behind him; Y stems up the field for his sail route; the back releases toward the flat. Panel 3, 2.0 seconds, as the quarterback reaches the top of his drop: the nickel, seeing the back come into the flat underneath him, widens for it, and the quarterback throws the sail behind him. Panel 4: Y catches it 13 yards downfield, in the space between the nickel and the corner, who is only now coming down from 19 yards deep. Three receivers at three depths against two defenders: the corner can take only the top one, and whichever of the lower two (the sail and the flat) the curl-flat defender takes, the other is open.

Flood is the purest Cover 3 beater because it uses Cover 3’s own rules against it. The corner’s rule (never let anyone behind you) means the go route takes him out of the play without a fight. The curl-flat defender’s rule (cover the curl, break to the flat) gives one man two receivers. The only help could come from the hook defender inside him or the post safety, and both are watching other routes. Four verticals works on the same arithmetic one level deeper: four vertical routes, three deep defenders, and a post safety who can be moved with the quarterback’s eyes. Y-cross and yankee attack the same single deep safety from across the field. In Y-cross the tight end runs a deep crosser behind the hook linebackers, who have dropped to 8 or 10 yards facing the quarterback and can’t see him go by, while a post or a go route holds the safety in the middle. The crosser comes out on the far side, 15 to 18 yards deep, in the space between the curl-flat defender (too shallow) and the corner (too deep, and occupied by the outside receiver). Every Cover 3 defender is where his rule says, and none of them has the crosser. Yankee does the same thing off play-action, with a post and a deep over route and a run fake that pulls the linebackers even further forward.

What Cover 3 does well doesn’t show in the grid at all, which is why its column has no orange. The grid grades pass concepts, and Cover 3’s strengths lie elsewhere: an eighth defender near the line against the run, and three deep defenders who never let anyone behind them, so it gives up very few explosive passes. What it concedes is the short and intermediate throw. In the charting data later in this chapter, every route type succeeds slightly more often than its own average against Cover 3. The defense’s bet is that a steady diet of 6-yard completions costs less than a light box or a busted deep ball.

Against quarters: make the safety’s eyes cost him

Quarters is built to stop most of what beats Cover 2 and Cover 3. It has four defenders who can play deep, so four verticals runs into four men; its safeties read the inside receiver and come down hard on anything short, so slants and short in-cuts thrown inside are dangerous. (The quick game still grades “+” against it because of the quick out by #2, thrown outside, away from those safeties, before the defender over the slot can widen.) Its weakness is the reverse of its strength. A read safety’s job is decided by one receiver, #2, and a route combination that tells him the wrong thing takes him out of the play.

Show the Python
def dagger_play():
    dfn = nickel("two", FS=(11.0, -7.0), SS=(11.0, 7.0), LCB=(7.5, -16.0), RCB=(7.5, 16.0),
                 WILL=(4.5, -4.5), NB=(5.0, 6.6), MIKE=(4.5, 1.2))
    p = Play(spread(rb_w=1.6), dfn, los=LOS, to_go=10)
    presnap(p)
    protect(p)
    timed(p, "RB", [(0.9, -4.2, 2.6), (1.6, -2.0, 6.0), (2.4, 0.0, 9.5)], "route")   # check, then release
    p.dropback(3.0)
    # dagger on the left: H straight up the seam, X a deep dig behind him
    timed(p, "H", [(1.2, 8.0, -9.0), (2.0, 14.0, -8.8), (3.2, 21.5, -8.4)], "route")
    timed(p, "X", [(1.9, 15.0, -15.0), (2.6, 16.0, -9.5), (3.3, 16.3, -3.0), (4.0, 16.5, 1.6)], "route")
    # the right side: Y up the seam holds the strong safety (a vertical #2 must be carried); Z go
    timed(p, "Y", [(1.2, 8.0, 9.0), (2.0, 14.0, 8.6), (3.2, 21.0, 7.6)], "route")
    timed(p, "Z", [(3.3, 22.0, 15.4)], "route")
    # the free safety carries the seam (H is #2 and vertical); the Will walls H, then sinks;
    # the corner plays X from outside and can only trail the dig
    timed(p, "FS", [(0.8, 11.5, -7.6), (1.8, 15.5, -7.6), (3.2, 20.0, -7.2)], "drop")
    timed(p, "WILL", [(0.8, 6.0, -6.5), (1.5, 8.0, -7.4), (2.6, 9.0, -6.6)], "drop")
    timed(p, "LCB", [(1.4, 11.5, -15.8), (2.0, 14.5, -15.4), (2.8, 15.0, -11.5), (3.3, 15.0, -7.0),
                     (4.0, 15.2, -2.6)], "drop")
    timed(p, "MIKE", [(1.2, 7.0, 0.8), (2.6, 9.0, 1.6)], "drop")
    timed(p, "SS", [(0.8, 11.5, 7.4), (1.8, 15.0, 7.0), (3.2, 19.5, 5.8), (4.0, 21.0, 5.4)], "drop")
    timed(p, "NB", [(1.0, 6.5, 8.0), (2.6, 9.0, 8.8)], "drop")                  # walls Y, then sinks
    timed(p, "RCB", [(1.6, 14.0, 16.6), (3.3, 21.0, 17.6)], "drop")
    p.pass_to("X", t=2.3)
    p.highlight("FS", "WILL")
    return p


dp = dagger_play()
animation_or_strip(dp, [0.0, 1.2, 2.3, 3.7],
                   ["1.  Snap · Quarters: the safeties read #2",
                    "2.  +1.2 s · #2 goes vertical: the FS carries him",
                    "3.  +2.3 s · The Will sinks short: throw the dig",
                    "4.  +3.7 s · Caught between the levels"],
                   ghosts=("FS", "WILL", "LCB"), ghost_t=0.0, lateral=(-21, 21), window=(-8.5, 25.5),
                   per_panel={0: dict(notes=[("reads #2", (14.5, -12.0), (11.0, -7.0))]),
                              1: dict(look=(12.0, -9.0), look_off=(1.4, 2.4)),
                              2: dict(look=(16.0, -3.0), look_label=""),
                              3: dict(opens=[((16.2, -1.0), (4.0, 6.5))])})
Figure 42.6: Dagger against quarters, simulated (a frame strip; a video on the web), run to the left this time. Panel 1: quarters from a nickel, the safeties 11 yards deep over the slot receivers, reading #2 (the free safety reads H). Panel 2: H (#2) goes straight up the seam, so by rule the free safety (ringed) carries him deep. The Will (ringed) walls H for a few steps and then sinks to his hook spot; the corner plays X from outside, as quarters corners do. Panel 3, 2.3 seconds: X breaks inside on a deep dig. The safety is gone with the seam, the Will has stopped at 9 yards, and the corner, outside, can only trail. The quarterback, whose eyes went from the safety to the Will, throws as X breaks. Panel 4: the dig is caught at about 16 yards in the middle of the field, under the safeties and over the linebackers. On the right, Y runs up the seam too, and that matters: a quarters safety must carry a vertical #2, so Y holds the strong safety on his side. Had Y stopped short, the strong safety would have been free to drive inside and rob the dig, which is why dagger is usually paired with a backside vertical.

Quarterback Play used this same matchup to show a progression in real time; here, look at it as a lesson about rules. The free safety did exactly what quarters asks: #2 went vertical, so he carried #2. The Will did what he was taught: wall the seam, then sink to his landmark. The corner played the outside receiver from outside, which is what lets quarters take away the deep outside. Every rule was obeyed, and together they left the middle of the field empty at 16 yards for a receiver breaking in from the outside. That is the general shape of attacking quarters: make #2 tell the safety something, then throw where the safety’s answer took him from. It is also why the backside matters: a defense that expects dagger can rob the dig with the other safety, if his own #2 stays short and frees him to look inside.

Scissors makes the safety’s answer cost him in a different way. Here #1 runs a post and #2 a corner route, so their paths cross at 10 to 12 yards. Each defender started with leverage, on the side his help isn’t: the safety inside #2, the corner outside #1. Once #2 goes vertical the safety must carry him, and when #2 breaks for the sideline the safety has to chase him outward, across the path of the post. The corner, playing #1 from outside, has to cross inward to follow the post. Both defenders are now chasing receivers who broke away from their leverage, and they have to run through each other to do it, a rub at depth. Well-coached quarters teams answer by trading the routes as they cross (the corner takes the corner route, the safety the post), but that takes a word and a split-second decision at full speed, and the hesitation is the window. The quick out by #2 attacks quarters underneath, in the first second, before the apex defender can widen (Quarters and the Two-High Match Family); the running back’s wheel and the bootleg flood do it at the edge.

The concepts quarters likes follow from the same rule. Levels and drive send two receivers from one side across the middle at two depths, the deeper one a dig at about 12 yards, and in both #2 breaks inside instead of going up the seam. In levels #2 runs the dig himself, straight at the read safety who was watching him all along. In drive #2 runs the shallow cross, which by rule frees the safety to stop backing up and drive on the next route coming inside: #1’s dig. Either way the deep in-cut meets a safety coming downhill with his eyes on it. That is the “−” in the quarters column. The same concepts grade “+” against Cover 0, Cover 1 and Cover 2 because their crossers and in-cuts run through traffic against man and settle between spot-dropping linebackers against Cover 2.

What quarters gives the offense for free, if it chooses to take it, is not in the matrix at all: runs. With two safeties at 10 to 12 yards and only six or seven defenders near the line, the box is light, and Run Fits and Box Math showed why a light box invites the offense to hand the ball off. Some of the best answers to two-high coverage aren’t passes.

Against man: run away, run through traffic

Man coverage has no zones to stretch, so the stretches of the zone concepts don’t apply. Smash against Cover 1 is just two one-on-ones, and both favour the defense. The slot defender on Y plays with outside leverage, because his help (the free safety) is inside, so the corner route breaks straight into the side he is protecting. And the corner on Z, with nobody running deep behind him to worry about, can sit on the hitch. Flood against man is three one-on-ones near a sideline, which crowds the space the receivers need. Man coverage loses in three different ways: traffic (receivers whose paths cross, so a defender chasing one runs into the other: mesh and every rub), leverage (routes that break away from the side the defender is protecting: the out against inside leverage, the slant against outside leverage), and talent (a receiver who simply beats his man). Mesh, the purest man-beater, gets the double “+” in the Cover 0 and Cover 1 columns; the figure in the two-way section below shows it.

2-Man is the exception that explains the rule. With two deep safeties over the top, the underneath defenders can trail their receivers with inside leverage and give up nothing deep, so the vertical concepts (four verticals, smash’s corner route, yankee) all run into a defender underneath and a safety above. It is the most orange column of the matrix for that reason: almost every concept built to stretch a zone is worse against it. Its weaknesses are short and outside, away from the trailing defenders: outs, stops and the flat route break away from their inside leverage, while slants break straight into it, which is why the quick game, a mix of both, grades only even. The other weakness is the quarterback’s legs: with every defender’s back turned to him, a scramble often gains more than any throw.

Against pressure: get it out, or throw it where they left

The last column is the one that answers Zone Blitzes, Fire Zones, and Simulated Pressure. Against any blitz the first answer is time: the deep concepts (dagger, scissors, yankee) need three seconds or more, so dagger and scissors grade orange against both Cover 0 and fire zones. Yankee grades even against Cover 0 for one reason: it is a play-action call with seven or eight blockers, so it can block an all-out blitz more often than a five-man dropback protection can, and a post and a deep over route against man with no safety behind them are a touchdown if the ball gets out. If the protection breaks, the quarterback, with his back half-turned on the fake, is hit before he can throw: grey means “depends.” The second answer depends on what is behind the blitz.

  • Cover 0 has nobody deep and everybody in man. The answer is the quick man-beater (mesh, slants, a rub) or the hot throw to the receiver whose defender blitzed, thrown before the extra rusher arrives. A one-on-one go route with no safety behind it is a touchdown if the ball can get out, which is why the cell for four verticals is grey rather than orange.
  • A fire zone has three deep and three underneath. It is built to take away the hot throw: the dropper lands in the window a hot slant or a quick in-cut wants. So the answers are the throws it can’t cover with three underneath: the seams, which the seam-flat defenders have to carry alone (four verticals and flood grade “+”), the window behind the dropper (a lineman can’t get much deeper than 5 or 6 yards in time), and screens, thrown behind rushers who have committed to the quarterback. Why does four verticals get a “+” here while dagger, which also sends a seam, gets a “−”? Timing. Four verticals throws the seam on rhythm, at the top of the drop, before the fifth rusher arrives, and it reads one defender who is alone. Dagger’s dig breaks at 15 or 16 yards behind the seam and needs a beat longer, and the middle dropper and the hook defender are sitting exactly where the dig crosses.

If the grid is this one-sided, why play Cover 3 or 2-Man?

Read the matrix literally and two coverages look like mistakes. Cover 3 is beaten by flood, four verticals, Y-cross and yankee and has no orange cell at all. 2-Man is orange almost everywhere, so why doesn’t every defense play it on every down? Yet in the charting data Cover 3 is the most common coverage in the league, on 32% of charted dropbacks from 2018 to 2022, and 2-Man is one of the rarest, on 2%.1

The grid grades pass concepts against coverages and nothing else, and each coverage pays its way somewhere the grid can’t see.

  • Cover 3 is cheap and sound. With one safety deep, the other can stand near the line as an eighth defender against the run, and three deep defenders who never let anyone behind them mean few explosive passes. It concedes completions underneath and dares the offense to string them together without a mistake. It is simple, so it is rarely blown, and it is the base that Cover 3 match, the fire zones and the rotations of Part 6 are built on.
  • 2-Man is expensive. It needs underneath defenders who can trail receivers all over the field, it leaves only five or six defenders near the line against the run, and with every back turned to the quarterback it invites scrambles. So it is a passing-down call. On third-and-7 or longer in those seasons it was 6% of charted dropbacks, still a small share. Played on every down, it would be run on and scrambled against; played rarely, it ambushes the vertical concepts offenses like to call on third-and-long.

A coverage’s real value is its whole column, plus the run game, plus how often it gets blown, weighted by the situations in which the defense chooses to play it. That is the defense’s half of the bet.

A short history: why the matrix keeps changing

The idea of choosing a pass play to beat a particular coverage is as old as coverages that could be studied. Sid Gillman, who coached the Los Angeles Rams in the late 1950s and the AFL’s Chargers in the 1960s, is usually credited with two of its foundations: studying opponents on film, cut up and spliced by play, and designing pass patterns to stretch a defense across the whole field, vertically and horizontally, so that zone defenders faced more receivers than they could cover. Bill Walsh, who said that much of what he did derived from Gillman, built those ideas into the West Coast offense’s progressions.2 The rules then tilted the field. In 1978 the NFL allowed defenders to contact a receiver only within the first five yards past the line of scrimmage, which made it far harder for defenses to disrupt routes and far more valuable for offenses to read coverage and throw on time (1978 and the Passing Revolution tells that story).3

The defense’s side of the history is the story of Part 6 told backwards. Four verticals against spot-drop Cover 3, a staple of the run-and-shoot and BYU passing games by the 1980s, helped produce pattern-matching Cover 3, usually traced to Nick Saban and Bill Belichick in Cleveland in the early 1990s (Cover 3).4 Smash and the quick out by #2 helped produce Palms, the quarters check that traps them. And the spread offenses of the 2000s and 2010s, which could create a one-on-one or a numbers advantage against any single coverage, helped push NFL defenses toward the disguised two-high shells that spread after 2018 (Fangio’s Two-High Revolution and Macdonald’s Answer). The matrix in this chapter is a snapshot of the mid-2020s. Its rows and columns will look different in ten years, because both sides are always working on the cells that hurt them.

Why “beaters” are bets

If offenses know which concept beats which coverage, why doesn’t every pass work? Because a beater only beats the coverage the defense actually plays, as it actually plays it, and four things stand between the call sheet and that coverage.

1. The defense chose its coverage too, and it hid it. The play-caller picks a concept before the snap, often before the huddle breaks, from a guess about the coverage. The defensive coordinator picks the coverage at the same time, from a guess about the concept, and then disguises it. Neither sees the other’s card. A smash call that meets Cover 2 looks brilliant on the replay; the same call against 2-Man looks like a mistake, and the play-caller is the same man with the same information. The rotation at the start of this chapter is the everyday version: the offense called a Cover 2 beater and got Cover 3. Keep that in mind when a broadcast calls a completion “a great call against that coverage.” The analyst is grading the call with the answer key in hand; the honest version is “that was a good bet, and it paid.”

2. Coverage labels hide different rules. “Cover 3” names a family, not a set of instructions. Against spot-drop Cover 3, four verticals is a math problem the defense loses; against Cover 3 match, whose seam-flat defenders carry the slot receivers, it meets four defenders deep and the math is gone. The label in the matrix is the same; the behaviour after the snap is not. Quarters, Cover 6 and Palms look identical before the snap and play completely differently against the same concept. Every match coverage is a set of if-then rules (Quarters and the Two-High Match Family), and the “beater” depends on which rules this staff teaches.

3. Execution and talent. A beater produces a window; somebody still has to hit it. The window in the smash plate is about five yards wide and opens for perhaps half a second. A protection that breaks at 2.2 seconds, a corner route run a yard too flat, a ball thrown a beat late, a defender who is simply faster than the diagram assumed: each closes it. And the reverse happens constantly. Great receivers beat good coverage with bad matchups, and great quarterbacks complete throws into coverages the play was not designed for. That is why the best players change the matrix, which describes average players.

4. Situation and the second read. The defense doesn’t play coverages at random; it plays them by down, distance, field position, personnel and score (Tendencies, PROE, and Charting). On third-and-long, a defense can sit back in deep coverage and concede the short throw, so a concept can “beat” the coverage and still lose the down if its open receiver is two yards short of the sticks. Beating the coverage and moving the chains are different things.

What the data say: the edges are real, and small

You can’t count concepts in public data: play-by-play records where the ball went, not what was drawn. But you can count something close to the matrix’s ingredients. Next Gen Stats charting in nflverse records, for many dropbacks, the coverage the defense played after the snap and the route run by the receiver who was targeted. Here is the success rate (the share of plays with positive expected points added) for each common route against each coverage, over five regular seasons.

Show the Python
cmap = LinearSegmentedColormap.from_list("od", [style.DEFENSE, "#f3f2ee", style.OFFENSE])
norm = TwoSlopeNorm(vcenter=SR_MEAN, vmin=0.28, vmax=0.68)
CLAB = ["Cover 0", "Cover 1", "2-Man", "Cover 2", "Cover 3", "Quarters\n(Cover 4)", "Cover 6"]
RLAB = ["Hitch / curl", "Out", "Slant", "Crosser", "In / dig", "Corner", "Post", "Go / fade"]
fig, ax = plt.subplots(figsize=(6.5, 4.4))
ax.imshow(SR.values, cmap=cmap, norm=norm, aspect="auto")
for i in range(len(ROUTES)):
    for j in range(len(COVS)):
        v, n = SR.values[i, j], NN.values[i, j]
        if n < 100:
            ax.add_patch(plt.Rectangle((j - 0.5, i - 0.5), 1, 1, fc=style.SURFACE, ec="none"))
            ax.text(j, i, f"n={n}", ha="center", va="center", fontsize=6.5, color=style.MUTED)
            continue
        ax.text(j, i, f"{100 * v:.0f}%", ha="center", va="center", fontsize=8,
                color="white" if abs(v - SR_MEAN) > 0.12 else style.INK)
ax.set_xticks(range(len(COVS)), CLAB, fontsize=7.8)
ax.set_yticks(range(len(ROUTES)), RLAB, fontsize=8)
ax.xaxis.tick_top()
ax.tick_params(length=0, labelcolor=style.INK)
ax.set_xticks(np.arange(-0.5, len(COVS)), minor=True)
ax.set_yticks(np.arange(-0.5, len(ROUTES)), minor=True)
ax.grid(which="minor", color=style.SURFACE, lw=2)
ax.grid(which="major", visible=False)
for s in ax.spines.values():
    s.set_visible(False)
ax.set_ylabel("Route run by the targeted receiver", fontsize=8, color=style.INK_2)
fig.tight_layout()
plt.show()
Figure 42.7: Success rate of targeted passes by the route the targeted receiver ran and the coverage the defense played after the snap, NFL regular seasons 2018–2022 (sacks excluded; a play is a success if it added expected points). Blue is above the average for these throws, orange below. Cells with fewer than 100 targets are greyed out and show only their count. The columns are the coverages the charters record, so Cover 6 appears and the matrix’s Cover 3 match and fire-zone columns don’t (charting files them under Cover 3). Compare along a row: most of the colour difference down the chart is between routes (go routes fail more often against everything), while within a route the coverage moves success rate by roughly 5 to 25 points. Hitches and curls succeed most against the spot-drop zones (Cover 2, Cover 3), where receivers settle in windows between underneath defenders, and least against 2-Man, where a trailing defender is on their hip with a safety behind him; corner routes do worst against man (Cover 1); go routes succeed most against Cover 2, the hole shot. No cell is near certainty. Source: nflverse play-by-play and participation data (Next Gen Stats coverage and route labels), course calculation.

Read it the way an analyst would. Across 63,058 targeted throws, the average success rate is 52%. The best cell is 63% and the worst 28%, but most of that spread is between routes, not between coverages: go routes are orange in every column because deep throws fail more often whatever the coverage, and hitches are blue in most. Within one route, the gap between its best and worst coverage runs from 6 points (crossers) to 24 (hitches). So read along a row.

Along the rows, some of the matrix’s logic shows clearly. A hitch or curl thrown against Cover 2 succeeds 63% of the time and against 2-Man only 38%: against Cover 2 the receiver settles in a window between underneath defenders who dropped to landmarks, while against 2-Man a defender is trailing on his hip with a safety over the top. Go routes do best against Cover 2 (43%), the hole shot behind a squatting corner, and worst against quarters (31%), which has a deep defender for every vertical route (only Cover 0, at 28%, is lower). Corner routes are a poor bet against Cover 1 (40%).5

Other cells seem to contradict the matrix, and each one teaches something about reading data like this.

  • The smash corner against Cover 2 succeeds only 49% of the time, below the chart’s average. But a corner route is a 20-yard throw toward the sideline, caught about half the time against most coverages, and success rate counts every incompletion as a failure. The corner route’s own average is 45%; against that baseline, Cover 2 is one of its better columns.
  • Slants and digs against Cover 3 succeed more often than average (61% and 58%), although four underneath defenders should make inside throws risky. Every route does a little better than its own average against Cover 3, the coverage that concedes underneath to protect against the deep ball, and a quarterback throws the slant against Cover 3 only after he has seen the hook defender leave its window. The cell records the result of a read, not of a call.
  • Crossers against man (Cover 1 53%, Cover 0 50%) succeed at about the crosser’s usual rate, with no sign of mesh’s double plus. The label lumps shallow crossers together with deep ones, and success rate calls a 6-yard catch on third-and-8 a failure however open the receiver was. It is also possible that the man-beater’s edge is simply smaller than coaching lore says, which is this section’s point.

Two cautions apply to every cell. First, the chart shows only the route thrown to, and the quarterback chooses that route after seeing the coverage, so every cell is already the result of someone’s read. Second, success rate punishes deep routes, which fail more often and win bigger. Neither caution changes the headline: even the best matchups fail more than a third of the time. A coverage beater moves the odds by a few points per throw. That still matters. Over a season of about 600 dropbacks, three points per throw is about 18 more successful plays, roughly one a game, which is why coordinators spend their week on it (The Game-Planning Week).

Calling against a menu, not a coverage

So a play-caller doesn’t pick the beater for the coverage; he picks the concept with the best expected result against the coverages this defense is likely to play in this situation. That is a weighted average, and you can do it with the matrix. Suppose that on second-and-7, film study says a defense plays Cover 3 35% of the time, Cover 1 25%, quarters 25% and Cover 2 15%. Score each grade as a number from −2 to +2, weight it by how often the coverage comes, and add. (This treats ordinal grades as if they were measurements: nobody knows that a “++” is exactly twice a “+”. It is a heuristic for organising a judgment, not a forecast of yards, and the ranking it produces matters more than the decimals.)

Table 42.2: A play-caller’s arithmetic: matrix grades weighted by a hypothetical defense’s second-and-7 coverage mix.
Concept Cover 3 (35%) Cover 1 (25%) Quarters (25%) Cover 2 (15%) Expected grade Worst case
Smash +1 −1 0 +2 +0.40 −1
Flood +2 −1 +1 +1 +0.85 −1
Mesh 0 +2 0 0 +0.50 0
Dagger 0 0 +2 +1 +0.65 0
Four verticals +2 0 −1 +1 +0.60 −1

Flood wins on average, because the most common coverage is the one it beats. But notice the last column. Flood is bad against man, and one snap in four is man. Mesh and dagger never go below zero. If the down is third-and-7 and a bad play ends the drive, a careful coordinator may prefer the call with no bad outcome to the one with the best average. That is the logic of the next section.

Two-way concepts: an answer for man and an answer for zone

A two-way concept has an answer built in for both man and zone coverage, so it isn’t a bad call whatever the defense plays. There are two ways to build one. The routes themselves can work against both (crossing routes rub against man and settle into holes against zone), or a receiver can change his route after the snap according to the coverage, the option route of Passing Game Fundamentals, whose runner breaks away from his defender against man and sits down in the window against zone. Mesh is the classic of the first kind.

Show the Python
def mesh_base(dfn, zone=False):
    q = Play(spread(rb_w=1.6), dfn, los=LOS, to_go=3)
    protect(q)
    q.dropback(2.5)
    if zone:   # the same crossers, settling in the first window past each hook defender
        route_to(q, "H", (3.8, -9.0), (6.4, -6.0), (6.6, 0.3))
        route_to(q, "Y", (2.6, 8.4), (5.2, 5.0), (5.8, -7.8))
    else:
        route_to(q, "H", (3.8, -9.0), (6.4, -6.0), (6.8, 9.5))
        route_to(q, "Y", (2.6, 8.4), (5.2, 5.0), (5.6, -10.5))
    route_to(q, "X", (10.0, -15.0), (16.5, -20.5)); route_to(q, "Z", (10.0, 15.0), (16.5, 20.5))
    route_to(q, "RB", (-3.4, 5.0), (0.2, 9.5), (1.2, 12.5))
    return q


fig, axes = plt.subplots(2, 1, figsize=(6.5, 8.4))
m = mesh_base(nickel("man", WILL=(4.2, 2.0), MIKE=(4.2, -1.6)))
for d_, t_ in (("LCB", "X"), ("RCB", "Z"), ("NB", "H"), ("SS", "Y"), ("WILL", "RB")):
    m.man(d_, t_)
m.rush("MIKE", pts=[(-4.0, 2.6)], speed=4.0)
m.highlight("NB", "SS")
fld = draw(m, ax=axes[0], lateral=(-23.5, 23.5), window=(-7.5, 19.5), width_in=6.5)
for d_, t_ in (("LCB", "X"), ("RCB", "Z"), ("NB", "H"), ("SS", "Y"), ("WILL", "RB")):   # bolder man lines
    (x0, y0), (x1, y1) = _P(fld, m, m.players[d_].d, m.players[d_].w), _P(fld, m, m.players[t_].d, m.players[t_].w)
    axes[0].plot([float(x0), float(x1)], [float(y0), float(y1)], color=style.DEFENSE, lw=1.4, ls=(0, (1, 1.6)),
                 zorder=7)
opening(fld, m, (6.2, 0.0), (2.8, 4.4))
say(fld, m, 10.0, -0.5, "mesh point: chasers\nrun into traffic", color=OD, fontsize=6.6)
say(fld, m, 15.0, 9.0, "man answer: throw the\ncrosser who comes out clean", color=GREEN, fontsize=6.8,
    weight="bold")
axes[0].set_title("Against Cover 1 (man): the rub", loc="left", fontsize=9.5, fontweight="bold")
# the zone panel is drawn after the drops: defenders at their landmarks, dashed outlines where they began
Z_PRE = {"LCB": (7.0, -15.8), "RCB": (7.0, 15.8), "FS": (13.5, 0.0), "NB": (5.0, -10.4), "SS": (6.0, 10.0),
         "WILL": (4.5, -2.6), "MIKE": (4.5, 1.8)}
Z_POST = {"LCB": (14.5, -16.5), "RCB": (14.5, 16.5), "FS": (15.5, 0.0), "NB": (7.5, -12.8), "SS": (7.5, 12.8),
          "WILL": (7.5, -4.5), "MIKE": (7.5, 4.5)}
z = mesh_base(nickel("one", **Z_POST), zone=True)
z.highlight("WILL", "MIKE")
fld = draw(z, ax=axes[1], lateral=(-23.5, 23.5), window=(-7.5, 19.5), width_in=6.5)
for k, (d0, w0) in Z_PRE.items():
    (x0, y0), (x1, y1) = _P(fld, z, d0, w0), _P(fld, z, *Z_POST[k])
    axes[1].plot([float(x0), float(x1)], [float(y0), float(y1)], color=style.DEFENSE, lw=1.0, ls=(0, (3, 2)),
                 zorder=3)
    ghost_marker(axes[1], float(x0), float(y0), z.players[k].label, fld.pts_per_yard())
opening(fld, z, (6.6, 0.3), (2.6, 5.0)); opening(fld, z, (5.8, -7.8), (2.4, 3.6))
say(fld, z, 17.6, 0.0, "zone answer: the crossers sit\nin the windows between defenders", color=GREEN,
    fontsize=6.8, weight="bold")
axes[1].set_title("Against Cover 3 (zone): sit in the holes", loc="left", fontsize=9.5, fontweight="bold")
fig.tight_layout(h_pad=1.2)
plt.show()
Figure 42.8: Mesh as a two-way concept, third-and-3. Top, against Cover 1 (a recap of the animation in Dropback Concepts): H and Y cross over the ball at 5 to 6 yards, H a step higher, so the defenders chasing them in man, the nickel ($) and the strong safety (SS), both ringed, have to get around one receiver to stay with the other (dotted lines are the man assignments). The Mike blitzes, so this is Cover 1 with five rushers; the back releases to the flat and the Will, who has him in man, goes with him. The quarterback throws to whichever crosser comes out of the traffic first. Bottom, the same play against Cover 3, drawn after the drops: each defender stands at the spot he dropped to, with a dashed outline where he started. Nobody is chasing, so each crosser settles in the first window past a hook defender (ringed) and turns to face the quarterback (green). The outside receivers’ corner routes do a different job in each picture: against man they take the two corners away from the crossers; against Cover 3 they pull the deep-third corners toward the sidelines. The back in the flat is the outlet.

Notice what the two-way concept costs. Against zone, mesh’s crossers are fine, settling for five or six yards in front of defenders who rally to them; they are not a zone beater the way flood is. In the matrix, mesh is grey across the zone columns: never bad, rarely great. That is the trade. A two-way concept gives up some of the ceiling of a pure beater to raise the floor. On third-and-3, where five or six yards is a first down and a bad call ends the drive, that is a bargain. On first-and-10, where a coordinator can afford a swing for a big gain, he may prefer the pure beater and accept that it will sometimes meet the wrong coverage.

There are three common ways offenses build two-way plays:

  • Routes that work against both. Mesh, drive and the shallow cross rub against man and find holes against zone. So does a slant run inside a defender with outside leverage.
  • Choices inside one route. The option route, a seam route that stays straight against one deep safety and bends into the open middle against two (a route conversion), and the hitch that turns into a fade against press: each receiver reads the coverage after the snap, and the quarterback reads the same thing.
  • A man side and a zone side. Put a zone beater on one half of the field (curl-flat, smash) and a man-beater on the other (a rub, a slant-flat), and let the quarterback choose his half from the man/zone read: the man/zone indicator on a motion before the snap, or the corners’ first steps after it. This is called a half-field or combination call, and many third-down playbooks are built from them.

All three ask more of the quarterback and the receivers than a single beater does, because now both of them must read the coverage the same way, at speed. When they disagree, the result is the interception where the receiver turned out and the ball went in. That is why two-way concepts are a veteran offense’s tool and why young quarterbacks are often given simpler, single-answer calls.

The defense answers back

If the offense’s job is to call the concept that beats the defense’s coverage, the defense’s job is to play a coverage that beats the offense’s concept, or at least doesn’t lose to it. Defenses fight the matrix in three ways.

Change the coverage’s rules against a known concept. This is the match idea from Part 6 seen as a counter. The clearest example is four verticals against Cover 3. Spot-drop Cover 3 loses to it by arithmetic; Cover 3 match changes one rule, the seam-flat defender’s, and the arithmetic is gone.

Show the Python
fig, axes = plt.subplots(1, 2, figsize=(6.5, 4.6))
for ax, kind in zip(axes, ("spot", "match")):
    q = Play(keep(spread(rb_w=1.6), -30, 1.0), keep(nickel("one", NB=(5.0, -8.6), SS=(6.0, 8.6)), -30, 1.0),
             los=LOS, to_go=None)
    route_to(q, "X", (8.0, -15.8), (24.0, -16.8)); route_to(q, "H", (6.0, -8.0), (24.0, -6.2))
    q.drop("LCB", (22.0, -17.0)); q.drop("FS", (18.5, -1.0)); q.drop("WILL", (9.0, -3.8))
    if kind == "spot":
        q.drop("NB", (11.0, -13.0))
    else:
        q.path("NB", [(17.5, -7.2)], absolute=True)
    q.highlight("NB")
    fld = draw(q, ax=ax, lateral=(-24.5, 3.0), window=(-6.5, 27.0), width_in=3.25, rule=False)
    if kind == "spot":
        opening(fld, q, (17.0, -6.8), (4.0, 4.0))
        point_to(fld, q, (-3.4, -12.4), (5.0, -8.6), "$ runs to his\ncurl spot", color=DD, fontsize=6.2)
        say(fld, q, 24.6, -11.0, "seam open between\nthe CB and the FS", color=GREEN, fontsize=6.2)
        say(fld, q, 21.5, -1.6, "FS: two seams,\none man", color=DD, fontsize=6.0)
        ax.set_title("Spot-drop Cover 3", loc="left", fontsize=9, fontweight="bold")
    else:
        point_to(fld, q, (-3.4, -12.4), (5.0, -8.6), "$ walls H and\ncarries him", color=DD, fontsize=6.2)
        say(fld, q, 24.6, -11.0, "a defender under the\nseam, the FS over it", color=DD, fontsize=6.2)
        ax.set_title("Cover 3 match", loc="left", fontsize=9, fontweight="bold")
fig.tight_layout(w_pad=0.8)
plt.show()
Figure 42.9: The defense’s counter to four verticals, left half of the field (H’s and X’s routes; the right side is the mirror image). Left, spot-drop Cover 3: the nickel ($, ringed) runs to his curl landmark, wide and about 11 yards deep, so H’s seam runs past him on the inside and arrives in the gap between the deep-third corner and the free safety (green). That gap exists because the free safety has two seams to cover, this one and its mirror on the right, and can’t take both. Right, Cover 3 match: the same nickel reads #2 (H) and, because H goes vertical, walls him and carries him up the seam. Now the seam has a defender underneath it and the free safety over it, and the ball has nowhere to go. One rule changed; the concept’s best throw disappeared. (Cover 3 draws both as moving plays.)

Match rules invite their own answers, and they are the counter-counters in the table below. A seam-flat defender who carries #2 vertically is not in the flat, so the back or a quick out by #1 is open underneath him. And route combinations that make two defenders’ rules collide create holes that no single rule covers. The cleanest is post-wheel, and it is why that concept gets the only “++” in the Cover 3 match column: #1 runs a post, and the corner, whose rule is to carry a vertical #1, goes inside with him; #2 starts toward the flat, so the seam-flat defender, by rule, goes with him underneath; then #2 turns up the sideline. The corner is inside, the seam-flat defender is trailing from below, and nobody is over the top of the wheel. A switch release does something similar at the snap: #1 and #2 cross, the outside receiver running inside and the slot outside, so the corner and the seam-flat defender each have to decide in their first step who is now #1 and who is #2. If they hesitate, or both take the same man, the other is free (Cover 3 draws both).

The same move, changing the rules, works against smash. Smash beats Cover 2 because the corner sits on the hitch and the safety starts too far inside for the corner route. Palms keeps the two-high picture but changes who covers whom on that side, and both defenders read #2. If #2 goes vertical, the safety carries him, and the corner, freed of any deep worry, plays #1 man to man, which means sitting on any short route by #1. If #2 instead breaks short to the flat, the corner jumps him and the safety takes #1. Against smash, #2’s corner route starts vertical, so the first rule applies.

Show the Python
pre = {"RCB": (6.5, 16.0), "SS": (11.0, 7.5), "NB": (4.5, 6.6)}
q = Play(keep(spread(), -6.0, 30), keep(nickel("two", FS=(11.0, -7.5), SS=pre["SS"], RCB=pre["RCB"],
                                            LCB=(7.5, -16.0), NB=pre["NB"], WILL=(4.5, -4.2), MIKE=(4.5, 1.2)),
                                     -6.0, 30), los=LOS, to_go=8)
protect(q)
q.dropback(2.5)
q.route("Z", r.hitch(6.0))
route_to(q, "Y", (10.5, 9.2), (18.0, 20.0))
q.path("SS", [(13.0, 9.4), (19.5, 18.0)], absolute=True)       # #2 vertical: the safety carries him, over the top
q.path("RCB", [(6.2, 15.6)], absolute=True)                     # #1 short: the corner sits on the hitch
q.drop("NB", (6.5, 10.0)); q.drop("MIKE", (8.5, 2.0)); q.drop("WILL", (8.0, -4.5))
q.highlight("RCB", "SS")
fld = draw(q, lateral=(-8.0, 25.0), window=(-8.0, 26.0))
say(fld, q, 22.0, 12.5, "#2 went vertical:\nthe SS carries the\ncorner route", color=DD, fontsize=6.8)
say(fld, q, 2.6, 21.0, "#1 stopped short:\nthe CB sits on\nthe hitch", color=DD, fontsize=6.8)
say(fld, q, 21.0, 0.5, "both smash throws covered:\nwork back to the checkdown", color=GREEN, fontsize=6.8)
for k, txt in (("Z", "#1"), ("Y", "#2")):
    pl = q.players[k]
    say(fld, q, pl.d - 2.4, pl.w, txt, fontsize=6.4)
plt.show()
Figure 42.10: Smash against Palms: the defense wins. Same two-high look before the snap, same smash to the right. But in Palms the corner and safety on this side both read #2 (Y). Y starts vertical, so by rule the strong safety (SS, ringed) carries him, and when Y breaks for the corner the safety is already over the top of him and inside, running with him toward the sideline. Z (#1) stops for his hitch, and the corner (CB, ringed), who no longer has to worry about anything deep, sits on it. Both of smash’s throws are covered, and the quarterback has to come off them to the other side of the field or the checkdown. The left side of the field is left out.

Why does the matrix call smash “even” against quarters but a loss against Palms, if a vertical #2 makes Palms play like quarters? Because plain quarters handles smash in much the same way, which is why that cell is grey, not blue. What Palms adds is the trap on the other branch: if the offense answers with a quick out by #2, the corner, reading #2 from the start, jumps it.

Take the beater’s target away directly. Brackets, robbers and lurkers put an extra defender where a known concept wants to throw (Man Coverage). A defense that expects mesh on third-and-short can sit a linebacker at the mesh point, at five yards over the ball, so the crossers run into him instead of past each other. A defense that expects dagger can rob the dig with a safety who ignores the seam: usually the backside safety, freed when his own #2 stays short, or a poach call that sends him across on purpose.

Make the coverage hard to identify. Disguise and late rotation don’t change the matrix; they hide which column the offense is in until it’s too late to use it. That is why a beater called before the snap is a bet and a beater chosen after the snap, by a quarterback reading the key defender, is much closer to a sure thing.

And the offense answers the answers. Every counter has a hole of its own, and the defense’s counter becomes the next concept’s target:

Table 42.3: Counters and counter-counters. Each answer creates the next question, which is why the matrix is never finished.
The defense’s counter What it takes away What it opens The offense’s counter-counter
Cover 3 match four verticals the flat and space behind carries post-wheel; switch releases; the back to the flat
Palms smash; quick outs by #2 the corner jumping #2 an out-and-up (an out that turns up the sideline) or wheel by #2; a double move by #1
Quarters poach, or a backside safety robbing dagger; deep crossers the backside receiver one-on-one a backside vertical to hold the safety; throw to the isolated backside receiver
Tampa 2 the seams between the safeties the Mike’s depth; the curl windows read the Mike: throw the seam he didn’t take; levels under him
Robber or lurk in-cuts and crossers the side he leaves look him off; throw behind him
2-Man vertical stretches out-breaking routes, the back, scrambles quick outs; RB routes; designed quarterback runs
Fire zone the hot throw the seams; the window behind the dropper seams; screens; throw over the dropper

Which side is ahead at any moment depends on who has the newer answer and the better players. That back-and-forth over many plays, how a coordinator sets up one call with another, is the subject of Constraint Theory: How Plays Talk to Each Other.

The alert: calling the shot before the snap

One more pre-snap tool turns the coverage read into a big play. An alert (many staffs say shot alert) is a pre-planned exception to the called play: if the quarterback sees a particular look before the snap, he throws to the alert receiver first, usually on a deep route; if he doesn’t see it, he runs the play as called. The play-caller builds it in; the quarterback decides at the line.

The classic trigger is a single deep safety with the offense’s best receiver isolated on the other side of the field, one-on-one against a corner with no help leaning his way. That is the situation in which a deep throw has the best odds and the highest payoff: the receiver only has to beat one man, and if he does, nobody is behind the corner. Other alerts are keyed to Cover 0 (any one-on-one deep with no safety at all), to a pressed corner whose leverage gives away the throw (one shaded inside with no deep help is conceding the fade or the back-shoulder throw outside; one shaded outside with no inside help is conceding the slant), or to a safety cheating down into the box against play-action. A shot play from Play-Action, Bootlegs, and Screens is called to take a deep shot; an alert is a shot that the defense has to give.

Why not just call the deep shot? Because the deep shot is a bad play against most coverages and a great one against a few, and the alert lets the offense take it only when the coverage shows that it is one of the few. The called play underneath is the insurance. What it costs is that the quarterback makes the decision before the snap, which is exactly the moment the defense is lying to him. Alerts are therefore built around looks that are hard to fake: a single safety who can’t get back to the alert side in time, whatever he does at the snap, or a corner pressed with no help. If the safety rotates over at the snap, a good quarterback abandons the alert and goes back to the play.

Putting it together: identify, then predict

Everything above reduces to a routine you can run on any passing play, live or on the replay: the quarterback’s four steps, minus the throwing. Call the shell and your two likeliest coverages; watch the safeties at the snap; let the corners name the coverage within its family; find the defender the routes are putting in conflict (two receivers to one sideline at two depths means a high-low on that side’s corner or curl-flat defender; a slot running up the seam means somebody’s rule about #2 is being tested); then say the open receiver out loud before the ball is thrown. The checklist in “Watch for it on Sunday” below is the pocket version.

The four animated plays in this chapter are drills for exactly this. Run them again (on the website they are videos; in print, cover panels 3 and 4 with your hand) and, at panel 2, name the coverage and the open receiver before you look.

Film room

The famous concept-against-coverage plays have homes of their own in this book: the Chiefs’ “Jet Chip Wasp” on third-and-15 in Super Bowl LIV is drawn in Case Study: Andy Reid’s Chiefs, and the Super Bowl XLIX interception at the goal line, a rub concept met by a defense ready for it, in Case Study: Belichick’s Patriots and the Game Plan. Here are three more recent pictures of this chapter’s ideas.

NoteFilm room: Chiefs, Super Bowls LVII and LVIII — the man-beater, and its counter

In Super Bowl LVII (February 12, 2023, the 2022 season) the Eagles played a lot of man coverage against Kansas City, and two of the Chiefs’ fourth-quarter touchdowns, the go-ahead score and the one that followed it, came from the same idea. On both, a receiver went in motion across the formation and then, as the ball was snapped, turned and ran back the way he had come. Kadarius Toney scored on the first; Skyy Moore on the second, after his defender started across the formation with him. “As soon as I went in motion and I saw him come in motion with me, I knew I had him,” Moore said afterwards. Andy Reid’s name for Toney’s play was “Corn Dog.”6

That is a man-beater in its purest form: it attacks the one thing man coverage must do, follow a receiver, and uses the defender’s own movement against him. A year later, in overtime of Super Bowl LVIII (February 11, 2024), the Chiefs ran the same motion on first-and-goal from the 3-yard line. This time the call, “Tom and Jerry,” was built on the assumption that the 49ers would be ready for it. “We built corn dog in saying, for sure they’ll cover corn dog,” Reid said. The first answer on the play was a shovel pass to running back Jerick McKinnon underneath; when the 49ers converged on the shovel and played man on the outside, Patrick Mahomes threw to Mecole Hardman, breaking back to the flat, for the championship-winning touchdown.7

What to notice: the play-caller designed for the defense’s counter to the beater, not for the beater itself. Note too that return motion only works against a defender who travels with the motion man; a defense that bumps, banjos or simply zones off the motion takes the edge away. On any goal-line snap, watch the first defender to react to a motion. If he follows, it’s man, and the motion man’s turn back is the throw.

NoteFilm room: Seahawks 2025 — two-high, and what offenses could do about it

Mike Macdonald’s 2025 Seahawks won Super Bowl LX playing more two-high coverage than any other playoff team: from Week 14, when safety Julian Love returned to the lineup, through the Super Bowl, Next Gen Stats counted split-safety coverage on 54.8% of their opponents’ pass plays, and Seattle won all eight of those games. Across the league, offenses converted 29.0% of dropbacks into first downs against split-safety coverage in 2025, tied for the lowest rate since at least 2018.8 (For a rough comparison from a different charting source, FTN’s 2025 labels in nflverse give a first-down rate of 29% against two-high and 34% against single-high coverage.9)

What to notice: this is the matrix’s quarters column in real life, and its Cover 6 column, which plays quarters on one half. Against two-high, the concepts that work are the ones that make a read safety pay for his rule (dagger, scissors, the quick out to #2) and, above all, the run, because two safeties 12 yards deep leave a light box. The league noticed: in 2025, offenses used fewer than three wide receivers on 41.7% of plays, the highest share since Next Gen Stats began counting in 2016.10 Bigger personnel is partly a run-game answer to two-high coverage. When you watch a two-high defense, count the run calls before you count the beaters.

NoteFilm room: Matthew Stafford, 2025 — the quarterback who beat two-high

Matthew Stafford won the 2025 MVP award with a league-leading 46 touchdown passes.11 In the nflverse charting, he was also among the best quarterbacks in the league against two-high coverage: on 249 dropbacks against Cover 2, 2-Man, quarters or Cover 6 he averaged +0.26 expected points added per dropback, third best of the 25 quarterbacks with at least 150 such dropbacks, against a league average of +0.02.12

What to notice: what a quarterback brings to the matrix. Two-high coverage is built to take away the deep throw and the easy read; it is beaten by a quarterback who identifies the coverage at the snap, moves a safety with his eyes and throws on time into a window between the levels: the dig behind a read safety, the seam the Mike didn’t carry. On a Rams passing down from 2025, watch Stafford’s helmet in the first second after the snap. It often goes where the ball isn’t going.

Watch for it on Sunday

TipWatch for it

Predict the open man. For one quarter, on every dropback pass, make the coverage call and then a prediction, before the ball is thrown.

  • Before the snap: shell (one-high or two-high), corners (press or off), and the two coverages you think are most likely. Is a receiver isolated against a single safety? That’s an alert candidate.
  • One second after the snap: how many safeties in the middle? Then the corners: squat (Cover 2), bail (Cover 3), read (quarters), trail (man). Say the coverage out loud.
  • Name the conflict defender on the side the routes are going: the corner (two receivers at two depths outside), the curl-flat defender (three at three levels), the read safety (a slot going up the seam), the matchup (crossers against man).
  • Predict the open receiver from what that defender does, before the throw. Then watch.
  • Watch the quarterback’s helmet. Did he look one way and throw the other? Who moved?

For your log: coverage called, receiver predicted, receiver thrown to. Score yourself on the predictions. Over a quarter you’ll find that you get Cover 3 and Cover 2 right far more often than quarters and match coverages, which is exactly the point of those coverages.

Predict the play

TipPredict the play 1: the isolated receiver
Show the Python
off = line() + [O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, -1.6, "R"), O("X", "WR", -0.7, -15.0),
                O("Y", "TE", -1.5, 7.5), O("H", "WR", -1.5, 11.5), O("Z", "WR", -0.7, 17.0)]
dfn = [D("LDE", "DE", 1.0, -5.5, "E"), D("LDT", "DT", 1.0, -0.7, "T"), D("RDT", "DT", 1.0, 2.35, "T"),
       D("RDE", "DE", 1.0, 5.5, "E"), D("WILL", "WILL", 4.5, -3.0, "W"), D("MIKE", "MIKE", 4.5, 1.8, "M"),
       D("SS", "SS", 4.0, 7.6, "SS"), D("NB", "NB", 2.0, 11.2, "$"), D("RCB", "CB", 1.5, 16.6, "CB"),
       D("LCB", "CB", 1.2, -14.0, "CB"), D("FS", "FS", 14.0, 4.5, "FS")]
p1 = Play(off, dfn, los=55, to_go=7)
p1.highlight("LCB", "FS")
fld = draw(p1, lateral=(-22, 22), window=(-7.5, 18.0))
for k, t in (("Z", "#1"), ("H", "#2"), ("Y", "#3")):
    pl = p1.players[k]
    say(fld, p1, pl.d - 2.6, pl.w, t, fontsize=6.4)
say(fld, p1, 16.0, 13.0, "called: flood to the trips side", color=OD, fontsize=6.8)
point_to(fld, p1, (7.5, -12.0), (1.2, -14.0), "press, shaded\ninside X", color=DD, fontsize=6.4)
point_to(fld, p1, (10.0, 8.8), (14.0, 4.5), "one safety, cheated\ntoward trips", color=DD, fontsize=6.4)
plt.show()
Figure 42.11: Second-and-7 near midfield. The offense is in trips to the right (#1, #2 and #3 labelled; #3 is Y, the tight end, flexed out off the line) with X alone on the left. The defense shows one deep safety, who is standing 4 or 5 yards toward the trips side, and man-looking corners: the left corner presses X from a shade inside him. The called play is a flood to the trips side.

Before the snap: does the quarterback stay with the called play, or is there a better throw?

This is the textbook alert: throw to X first. One deep safety, already leaning toward the trips, means X is one-on-one with no help on his side. The corner pressing him is shaded inside, so he is taking away the slant and conceding the outside: the alert throw is a fade or a back-shoulder throw up the left sideline. If X wins at the line, the throw has a high chance of a big gain, and the safety, 4 or 5 yards the wrong way and 14 deep, can’t get there in time.

The insurance: if the safety rotates back toward X at the snap, or the corner bails off the press, the alert is off and the quarterback works the flood to the trips side, where three receivers now face a defense that has shifted its help that way. And the defense knows all of this: a single safety cheating to trips is sometimes bait for exactly this throw, with a rotation back at the snap. That is why an alert is decided before the snap but confirmed in the first half-second after it.

TipPredict the play 2: 1.1 seconds into four verticals
Show the Python
def p2_play():
    p = Play(spread(rb_w=1.6), nickel("c2", WILL=(4.5, -4.2), NB=(4.5, 6.6), MIKE=(4.5, 1.2)), los=LOS, to_go=8)
    protect(p)
    p.dropback(3.0)
    for k, s in (("X", -1), ("Z", 1)):
        timed(p, k, [(2.6, 18.0, s * 16.0)], "route")
    for k, s in (("H", -1), ("Y", 1)):
        timed(p, k, [(2.6, 18.0, s * 7.5)], "route")
    timed(p, "RB", [(0.8, -4.0, 2.8), (1.5, -2.5, 5.5)], "route")
    timed(p, "MIKE", [(1.1, 10.5, 3.6)], "drop")                  # the Tampa Mike runs the middle, leaning right
    timed(p, "FS", [(1.1, 16.0, -10.5)], "drop"); timed(p, "SS", [(1.1, 16.0, 10.5)], "drop")
    timed(p, "LCB", [(1.1, 6.0, -18.0)], "drop"); timed(p, "RCB", [(1.1, 6.0, 18.0)], "drop")
    timed(p, "WILL", [(1.1, 8.5, -11.5)], "drop"); timed(p, "NB", [(1.1, 8.5, 12.0)], "drop")
    p.highlight("MIKE", "FS", "SS")
    return p


p2 = p2_play()
fld = snapshot(p2, 1.1, ghosts=("MIKE", "FS", "SS", "LCB", "RCB"), ghost_t=0.0, lateral=(-22, 22),
               window=(-9.5, 20.0))
ruler(fld, p2)
plt.show()
Figure 42.12: Second-and-8. The offense runs four verticals. The picture is 1.1 seconds after the snap; dashed outlines show where the ringed defenders started. Both corners squatted at about 6 yards. The two safeties have widened to about 10 or 11 yards outside the middle and 16 deep. The Mike (M, ringed) has turned and is running down the middle of the field, drifting toward the right-hand seam.

What is the coverage, which defender should the quarterback read, and where will the ball go?

Tampa 2. Two safeties splitting the field (middle open), corners squatting in the flats (Cover 2 corners), and the Mike running down the middle: that is the Tampa 2 Mike, whose job is to carry the most dangerous seam and close the gap between the safeties that four verticals is built to hit.

Read the Mike, then a safety. The Mike can only carry one seam. Whichever he takes, the other seam is a one-on-one high-low on that side’s safety: the seam inside him and the go route outside him. If the safety stays inside on the seam, the go route is open along the sideline behind the squatting corner (the hole shot); if he widens toward the go route, as these two already have, the seam splits the gap between him and the Mike. Here the Mike has opened toward Y’s seam on the right, so the throw is H’s seam on the left, between the Mike and the free safety. This is where the look-off earns its keep: a quarterback who wants that throw holds his eyes on Y’s seam for a beat to keep the Mike drifting right, and many offenses coach the seam runners to bend away from the Mike as well. If the quarterback can’t decide in time, the back underneath, past the two hook defenders who have dropped deep under the verticals, is the checkdown. This is why four verticals is only a “+” against Cover 2 in the matrix, not a “++”: the Tampa Mike takes away half of the concept.

TipPredict the play 3: you call it
Show the Python
p3 = Play(spread(), nickel("two", LCB=(6.0, -15.8), RCB=(6.0, 15.8), MIKE=(4.5, 4.4)), los=60, to_go=7)
fld = draw(p3, lateral=(-22, 22), window=(-7.5, 17.0))
plt.show()
Figure 42.13: Third-and-7 near midfield, your offense in its 2x2 set. The defense shows two-high with both corners 6 yards off. Film study says that on third-and-medium against this formation it played Cover 2 30% of the time, quarters 35%, 2-Man 20%, and rotated to Cover 3 the other 15%.

You have four concepts on the call sheet: smash, flood, dagger and mesh. Using the matrix grades (reprinted below), which has the best expected result? Which has the safest floor? Which would you call, and why?

Table 42.4: The four rows of the matrix you need, with this defense’s coverage mix.
Concept Cover 2 (30%) Quarters (35%) 2-Man (20%) Cover 3 (15%)
Smash +2 0 −2 +1
Flood +1 +1 −1 +2
Dagger +1 +2 −1 0
Mesh 0 0 +1 0

Weight each grade by the coverage mix (Cover 2 30%, quarters 35%, 2-Man 20%, Cover 3 15%):

  • Smash: +2, 0, −2, +1 → 0.60 + 0 − 0.40 + 0.15 = +0.35, worst case −2 (2-Man).
  • Flood: +1, +1, −1, +2 → 0.30 + 0.35 − 0.20 + 0.30 = +0.75, worst case −1.
  • Dagger: +1, +2, −1, 0 → 0.30 + 0.70 − 0.20 + 0 = +0.80, worst case −1.
  • Mesh: 0, 0, +1, 0 → +0.20, worst case 0.

Dagger has the best average, because the most likely coverage, quarters, is the one it was built to beat, and it is decent against Cover 2 too. Flood is a close second. Mesh never loses but rarely wins big. Smash, the famous Cover 2 beater, is the worst choice here: this defense plays enough 2-Man to punish it.

What a coordinator would add. Third-and-7 is a long-ish third down, and route depth matters as much as the grade. Dagger’s dig, at 15 or 16 yards, is past the sticks. Mesh’s crossers settle at 5 or 6 yards against zone, short of the line to gain, so its “safe floor” is less safe than it looks: a completed mesh crosser that is tackled a yard short still ends the drive. But dagger needs about three seconds, so the call depends on the protection and on whether this defense blitzes on third down; against a pressure-heavy defense the slightly quicker flood, or a two-way call, might be safer. And the 20% of 2-Man is the danger in every choice except mesh: if the 2-Man share were higher, or the down shorter, mesh’s floor would start to look like the smart call. The matrix doesn’t make the decision; it organises it.

Takeaways

  • The quarterback reads coverage in four steps: the shell before the snap (a hypothesis), the rotation at it (the middle open or closed one second later), the key defender after it (the one the concept puts in conflict), and the throw that defender leaves. The look-off is the same read run in reverse: move the key defender with your eyes, then throw where he was.
  • Every cell of the concept-by-coverage matrix follows from two questions: where are this coverage’s thin spots, and does it give help to the defender this concept attacks? Smash beats Cover 2 at the sideline; flood and four verticals beat Cover 3’s arithmetic; dagger and scissors make quarters’ read safeties pay for their rule; mesh beats man with traffic; quick throws, seams and screens beat pressure. Against split-field coverage, read each half on its own. The grid leaves out the run game, which is where Cover 3 and the two-high shells earn their keep.
  • Beaters are bets. Disguise hides the coverage, match rules change what a label means, execution and talent widen or close windows, and the defense chooses by situation too. In charting data the edges are real but small: even the best route-against-coverage matchups fail more than a third of the time.
  • Two-way concepts trade ceiling for floor. Built-in answers for man and for zone mean the call is never bad, at the cost of rarely being great; they rule third down.
  • The matrix is never finished. Every defensive counter (Cover 3 match, Palms, Tampa 2, robbers) opens something new, and the offense’s next concept attacks it. The shot alert lets the offense take a deep shot only when the coverage gives it.
  • Watching: call the coverage one second after the snap, find the conflict defender, and predict the open man before the throw.

Connections

Builds on: Dropback Concepts (the concepts and the defender each one attacks), Quarterback Play (the progression and the key defender), Man Coverage, Cover 3, Cover 2 and Tampa 2 and Quarters and the Two-High Match Family (each coverage’s thin spots), Disguise, Rotation, and Split-Field Coverage (why the pre-snap read is only a hypothesis) and Zone Blitzes, Fire Zones, and Simulated Pressure (the pressure column).

Sets up: Constraint Theory: How Plays Talk to Each Other, which turns the counter-and-counter-counter table into a theory of play-calling; The Game-Planning Week, where coordinators build the call sheet from the opponent’s coverage tendencies, the matrix arithmetic done for real; and Third Down: The Money Down, where two-way concepts and pressure answers decide drives. The Coverage and Pressure Atlas keeps a one-page copy of the matrix.

Case studies: Case Study: Belichick’s Patriots and the Game Plan (taking away what an offense does best, week by week, and the Super Bowl XLIX interception) and Case Study: Andy Reid’s Chiefs (Jet Chip Wasp, and an offense built on beating whatever coverage it gets).

NoteGo deeper
  • Chris B. Brown, The Essential Smart Football (2012) and The Art of Smart Football (2015): short, clear essays on concepts, coverages and the quarterback’s read, including smash, four verticals and the coverage-beater idea.
  • Cody Alexander, Match Quarters and his MatchQuarters newsletter: how modern defenses build rules that take away specific concepts, from the defensive coach’s side.
  • Ted Nguyen’s film breakdowns at The Athletic and Emory Wilhite’s newsletter: concept-against-coverage cut-ups from NFL games, play by play.
  • NFL Next Gen Stats’ coverage articles on NFL.com: league-wide numbers on two-high, man and blitz rates, season by season.

  1. Course calculation from nflverse play-by-play joined to participation data, NFL regular seasons 2018–2022, quarterback dropbacks whose post-snap coverage Next Gen Stats charted as Cover 0, 1, 2, 3, 4 or 6 or 2-Man (prevent excluded); third-and-long means third down with 7 or more yards to go. Two-high coverage has grown since: Next Gen Stats measured split-safety coverage on 42.0% of plays in 2025, the highest since its tracking began in 2018 (NFL.com, “The coverage that turned the Seahawks into Super Bowl winners and is taking the NFL by storm,” 2026, cited in full in the Seahawks film room).↩︎

  2. “Sid Gillman,” Pro Football Hall of Fame (Class of 1983; Chargers head coach and general manager 1960–1969): https://www.profootballhof.com/players/sid-gillman/ ; “Sid Gillman,” Wikipedia: https://en.wikipedia.org/wiki/Sid_Gillman (Rams head coach 1955–1959, Chargers 1960–1969 and 1971; his early film study; using “the length and width of the field”; Walsh’s acknowledgement that “much of what he did derived from Gillman”). Walsh never coached on Gillman’s staff; the influence came through Gillman’s disciples, Al Davis among them.↩︎

  3. Pro Football Hall of Fame, “1978” (football history chronology): https://www.profootballhof.com/football-history/football-history/1960-1979/1978 (“Rules changes permitted a defender to maintain contact with a receiver within five yards of the line of scrimmage, but restricted contact beyond that point.”)↩︎

  4. Cameron Soran, “The Complete Guide to Nick Saban Coverages at Alabama,” Throw Deep Publishing (Feb. 24, 2021): https://throwdeeppublishing.com/blogs/news/nick-saban-s-alabama-pass-coverages (a pattern-matching form of Cover 3 that “prior to his association with Belichick with the Browns in the early 1990s simply did not exist”). Saban was Cleveland’s defensive coordinator under Belichick from 1991 to 1994. Which offenses forced the change is the usual coaching account, not a documented record.↩︎

  5. Course calculation from nflverse play-by-play (load_pbp) joined to participation data (load_participation), NFL regular seasons 2018–2022, pass attempts with a targeted receiver, sacks excluded, route and defense_coverage_type both recorded. Both labels come from Next Gen Stats for these seasons; 2023–2025 participation comes from FTN with different route and coverage labels, so those seasons are not pooled here. “Success” is nflverse’s success flag (expected points added greater than zero). The route is the targeted receiver’s only, as charted. In the same sample, corner routes averaged about 21 air yards and were caught on roughly 45–51% of targets against the zone coverages, and every one of the eight route types had a higher success rate against Cover 3 than its own average across all coverages.↩︎

  6. Jonathan Jones, “Super Bowl 2023: Patrick Mahomes, Chiefs outmanned Eagles defense when it mattered the most,” CBS Sports (Feb. 13, 2023): https://www.cbssports.com/nfl/news/super-bowl-2023-patrick-mahomes-chiefs-outmanned-eagles-defense-when-it-mattered-the-most (the Eagles’ man coverage; Toney’s touchdown came with Kansas City trailing 27–21 in the fourth quarter, Moore’s less than three minutes later off similar motion; Moore’s quote). The play name: Bryan DeArdo, “‘Corn dog’ joins Chiefs Super Bowl lore: Andy Reid says Kadarius Toney TD came on a play with an unusual name,” CBS Sports (Feb. 13, 2023): https://www.cbssports.com/nfl/news/corn-dog-joins-chiefs-super-bowl-lore-andy-reid-says-kadarius-toney-td-came-on-a-play-with-an-unusual-name .↩︎

  7. Jason Owens, “Andy Reid surprised that 49ers bit on game-winning Super Bowl motion: ‘For sure they’ll cover corn dog,’” Yahoo Sports (Feb. 13, 2024): https://sports.yahoo.com/andy-reid-surprised-49ers-bit-on-game-winning-super-bowl-motion-for-sure-theyll-cover-corn-dog-232659275.html (Reid’s quotes; the 49ers “converged on the shovel” and “manned it up on the outside”). Score and overtime: Chiefs 25, 49ers 22 (OT), per the course fact sheet. First-and-goal from the 49ers’ 3, the 3-yard touchdown, and the shovel to McKinnon as the play’s designed first option: “Tom and Jerry (American football),” Wikipedia: https://en.wikipedia.org/wiki/Tom_and_Jerry_(American_football) .↩︎

  8. NFL Next Gen Stats Analytics Team, “The coverage that turned the Seahawks into Super Bowl winners and is taking the NFL by storm,” NFL.com (2026, after Super Bowl LX; the page carries no date): https://www.nfl.com/news/the-coverage-that-turned-the-seahawks-into-super-bowl-winners-and-is-taking-the-nfl-by-storm (54.8% from Week 14, Love’s first game back, through Super Bowl LX, “the highest rate of any playoff team in that span”; 46% in the nine games he missed; 8–0 and 15.1 points allowed after his return; 29.0% first-down rate, “tied for the lowest mark since at least 2018”). Split-safety is NGS’s post-snap two-high measure; do not mix it with the TruMedia/538 early-down series.↩︎

  9. Course calculation from nflverse play-by-play joined to participation data, 2025 regular season, quarterback dropbacks with a charted defense_coverage_type (FTN charting), BLOWN and COMBO excluded; two-high = COVER_2, 2_MAN, COVER_4, COVER_6; single-high = COVER_1, COVER_3; first down = nflverse’s first_down flag. FTN’s labels and NGS’s split-safety measure are built differently, so compare the two figures loosely.↩︎

  10. NFL Next Gen Stats Analytics Team, “NFL trend watch: heavy personnel could shape Super Bowl LX showdown between Patriots and Seahawks,” NFL.com (2026): https://www.nfl.com/news/nfl-trend-watch-heavy-personnel-could-shape-super-bowl-lx-showdown-between-patriots-and-seahawks (“Offenses used sub packages with fewer than three wide receivers on 41.7% of plays; the average had been below 38% in every one of the prior nine seasons since Next Gen Stats was established in 2016”).↩︎

  11. “List of NFL Honors award winners from 2025 NFL season,” NFL.com: https://amp.nfl.com/news/list-of-nfl-honors-award-winners-from-2025-nfl-season .↩︎

  12. Course calculation from nflverse play-by-play joined to participation data, 2025 regular season, quarterback dropbacks (sacks and scrambles included) with a charted defense_coverage_type, BLOWN and COMBO excluded; two-high = COVER_2, 2_MAN, COVER_4, COVER_6. The 2025 coverage labels come from FTN charting. A ranking by one season’s EPA on a subset of plays is noisy; read it as “among the best,” not as an exact order.↩︎