Run Fits: Gap Integrity, Force, Spill, and Box Math

Why a defensive end throws himself under a pulling guard on purpose, and how eleven defenders turn a run into arithmetic

Show the Python (shared helpers for this chapter’s diagrams)
import logging
logging.getLogger("matplotlib.font_manager").setLevel(logging.ERROR)
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Ellipse, FancyArrowPatch, Rectangle, RegularPolygon
from gridiron import Play, Player, Field, offense, technique, style

GREEN = "#0f7a55"         # darker step of the aqua highlight, for text on the light field
PURPLE = style.SERIES[6]  # a ring colour that is neither offense blue nor defense orange
# Ring colours keep one meaning in every figure of this chapter:
FORCE_RING = PURPLE           # the force (or the plus-one)
ALLEY_RING = GREEN            # the alley player or another free fitter
WATCH_RING = style.DEFENSE    # the defender whose technique the figure is about
BALL_RING = style.INK_2       # the ball carrier (neutral)
OL_KEYS = ("LT", "LG", "C", "RG", "RT")


def pdf_build():
    return os.environ.get("RTG_FORMAT", "").lower() in ("pdf", "typst", "print")


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


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


def T(t, side=1):
    """Width of technique t on the offense's right (side=+1) or left (side=-1)."""
    return technique(t, side)


def line(labels="none", puller=None):
    """The five offensive linemen ("none": only the center lettered, as in the other run chapters).
    `puller` letters one more lineman "G" (the guard the figure is about)."""
    out = []
    for p in offense("singleback"):
        if p.key in OL_KEYS:
            lab = p.key if labels == "full" else ("C" if p.key == "C" else ("G" if p.key == puller else ""))
            out.append(p.moved(label=lab))
    return out


def te(side=1, key=None, d=-0.7):
    key = key or ("Y" if side > 0 else "U")
    return O(key, "TE", d, side * 4.8, key)


def i_form(wrs=True, puller=None):
    """I-formation, 21 personnel, tight end (Y) on the right; X on the line left, Z off the ball right."""
    out = line(puller=puller) + [O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.9, 0, "F"), O("RB", "RB", -7.4, 0, "R"), te(+1)]
    if wrs:
        out += [O("X", "WR", -0.7, -15.0, "X"), O("Z", "WR", -1.5, 15.0, "Z")]
    return out


def single_back_11(gun=False):
    """11 personnel 2x2: Y in line right, Z wide right, H in the left slot, X wide left (X on the line)."""
    qb = O("QB", "QB", -5.0 if gun else -1.9, 0, "Q")
    rb = O("RB", "RB", -5.0, -1.6, "R") if gun else O("RB", "RB", -7.0, 0, "R")
    return line() + [qb, rb, te(+1), O("Z", "WR", -1.5, 15.0, "Z"), O("H", "WR", -1.5, -9.0, "H"),
                     O("X", "WR", -0.7, -15.0, "X")]


def over_front(side=1):
    """The 4-3 Over of Gap and Power Runs: 5, 1, 3, 5 on the line from the offense's left, the Sam walked up
    on the line outside the tight end (a wide 9; 05-02 draws the Over's Sam off the ball), the Mike over the
    strong A gap, the Will over the weak B gap."""
    s = side
    return [D("WE", "DL", 1.0, T("5", -s), "5"), D("NT", "DL", 1.0, T("1", -s), "1"),
            D("DT", "DL", 1.0, T("3", s), "3"), D("SE", "DL", 1.0, T("5", s), "5"),
            D("SAM", "SAM", 1.0, s * 7.0, "S"), D("MIKE", "MIKE", 4.6, s * 0.9, "M"),
            D("WILL", "WILL", 4.6, -s * 2.5, "W")]


def even4(sam_w=None):
    """A four-man even front (5, 1, 3, 5 from the left; 3-technique to the right) with two or three linebackers.
    The right end is a true 5 (outside shoulder of the tackle, inside the tight end)."""
    out = [D("WE", "DL", 1.0, T("5", -1), "5"), D("NT", "DL", 1.0, T("1", -1), "1"),
           D("DT", "DL", 1.0, T("3", 1), "3"), D("SE", "DL", 1.0, T("5", 1), "5"),
           D("MIKE", "MIKE", 4.6, 1.2, "M"), D("WILL", "WILL", 4.6, -2.4, "W")]
    if sam_w is not None:
        out.append(D("SAM", "SAM", 4.2, sam_w, "S"))
    return out


def go_to(p, key, end, kind="block", delay=0.0, speed=None, via=()):
    """Move `key` through absolute (d, w) points `via` to `end`, as a block, pull, path or run."""
    start = np.array(p._cur(key))
    pts = [tuple(np.array(q) - start) for q in (*via, end)]
    if kind == "block":
        return p.block(key, pts=pts, delay=delay, speed=speed)
    if kind == "pull":
        return p.pull(key, pts, delay=delay, speed=speed)
    return {"path": p.path, "run": p.run}[kind](key, pts, delay=delay, speed=speed)


def _P(fld, p, d, w):
    return fld.xy(*p.to_abs(d, w))


def say(fld, p, d, w, text, color=style.INK_2, fontsize=7.2, ha="center", weight="normal"):
    """A short on-field label at (d, w)."""
    x, y = _P(fld, p, d, w)
    fld.ax.text(x, y, text, fontsize=fontsize, color=color, ha=ha, va="center", zorder=9, fontweight=weight,
                bbox=dict(boxstyle="round,pad=0.18", fc=style.SURFACE, ec="none", alpha=0.9))


def point_to(fld, p, text_at, target, text, color=style.INK_2, fontsize=6.8, shrink=7, weight="normal"):
    """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="center", va="center", zorder=9, fontweight=weight,
                    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.9))


def gap_tag(fld, p, d, w, text, color=GREEN, fontsize=7.5):
    """A gap letter (or a short owner tag) in a small rounded box."""
    x, y = _P(fld, p, d, w)
    fld.ax.text(x, y, text, fontsize=fontsize, color=color, ha="center", va="center", zorder=9,
                fontweight="bold", bbox=dict(boxstyle="round,pad=0.2", fc=style.SURFACE, ec=color, lw=1.0))


def spot(fld, p, d, w, color=style.DEFENSE_DARK, ms=10):
    """Mark a point (a tackle, a meeting point) with an X."""
    x, y = _P(fld, p, d, w)
    fld.ax.plot([x], [y], marker="X", ms=ms, color=color, mec="white", mew=0.8, zorder=12)


def lane(fld, p, w0, w1, d0, d1, color=style.OFFENSE, alpha=0.10, ls=(0, (3, 2))):
    """Shade a rectangle from width w0 to w1 and depth d0 to d1 (a lane, the box, a zone of free yards)."""
    (x0, y0), (x1, y1) = _P(fld, p, d0, w0), _P(fld, p, d1, w1)
    fld.ax.add_patch(Rectangle((min(x0, x1), min(y0, y1)), abs(x1 - x0), abs(y1 - y0), fc=color, alpha=alpha,
                               ec=color, lw=0.9, ls=ls, zorder=0.8))


def dashed(fld, p, pts, color=style.THIRD, lw=1.5, dash=(0, (3, 2.2)), end="arrow"):
    """A dashed 'what if' or 'intent' path through absolute (d, w) points."""
    xs, ys = _P(fld, p, np.array([q[0] for q in pts]), np.array([q[1] for q in pts]))
    xs, ys = np.asarray(xs, float), np.asarray(ys, float)
    if end == "arrow":
        hx, hy = xs[-2] + 0.75 * (xs[-1] - xs[-2]), ys[-2] + 0.75 * (ys[-1] - ys[-2])
        xs = np.concatenate([xs[:-1], [hx, xs[-1]]]); ys = np.concatenate([ys[:-1], [hy, ys[-1]]])
        fld.ax.plot(xs[:-1], ys[:-1], color=color, lw=lw, ls=dash, zorder=6)
        fld.ax.add_patch(FancyArrowPatch((xs[-2], ys[-2]), (xs[-1], ys[-1]), arrowstyle="-|>",
                                         mutation_scale=10, color=color, lw=lw, zorder=6))
    else:
        fld.ax.plot(xs, ys, color=color, lw=lw, ls=dash, zorder=6)


def ghost(fld, p, d, w, label="", color=style.DEFENSE):
    """A faded defender marker: where a player stood before the snap."""
    x, y = _P(fld, p, d, w)
    fld.ax.add_patch(RegularPolygon((float(x), float(y)), 4, radius=0.94, orientation=np.pi / 4, fc="none",
                                    ec=color, lw=1.0, ls=(0, (2, 1.5)), alpha=0.7, zorder=5))
    if label:
        fld.ax.text(float(x), float(y), label, fontsize=6, color=style.MUTED, ha="center", va="center", zorder=5)


def clean(ax):
    """Box-zoomed diagrams: drop hash ticks and yard numbers, clip anything outside the window."""
    for ln in list(ax.lines):
        xs, ys = ln.get_data()
        if len(xs) == 2 and ln.get_linewidth() == 0.5 and np.hypot(xs[1] - xs[0], ys[1] - ys[0]) < 1.0:
            ln.remove()
    for t in list(ax.texts):
        if t.get_text().isdigit() and t.get_alpha() == 0.55:   # yard numbers, not technique labels
            t.remove()
        else:
            t.set_clip_on(True)


def draw(p, width_in=5.8, ax=None, **kw):
    """Play.draw, sized for the page, cleaned for a box-sized window. A diagram with its own figure
    fills it edge to edge (matplotlib's default margins would shrink an equal-aspect field)."""
    fld = p.draw(width_in=width_in, ax=ax, **kw)
    clean(fld.ax)
    if ax is None:
        fld.fig.subplots_adjust(left=0.01, right=0.99, bottom=0.01,
                                top=0.93 if (kw.get("title", True) and p.title) else 0.99)
    return fld


def subtitle(ax, text):
    ax.set_title(text, fontsize=9, loc="left", color=style.INK, fontweight="bold")


# --- frame strips (PDF) and video (web) for the simulated plays --------------------------------------
MARK_R = 0.62


def tracking(play):
    df = play.to_tracking()
    df["_id"] = df["displayName"].astype(str)
    return df


def panel(ax, play, df, t, lateral, window, rings=(), ring_r=0.9):
    """One moment of a simulated play on `ax`: markers, trails of on-screen players, rings."""
    tmap = df.groupby("frameId")["time"].first()
    fid = int((tmap - t).abs().idxmin())
    ylo, yhi = sorted((play.ball_y - lateral[0], play.ball_y - lateral[1]))
    fld = Field(ax=ax, orient="vertical", los=play.los, window=window, numbers=False, hashes=False,
                lateral=(ylo, yhi), to_go=play.to_go)
    cur = df[df["frameId"] == fid]
    snap = df[df["frameId"] == int((tmap - 0.0).abs().idxmin())]
    first = snap[snap["x"].between(play.los + window[0] + 0.8, play.los + window[1] - 0.8)
                 & snap["y"].between(ylo + 0.8, yhi - 0.8)]       # players whose marker fits at the snap
    ids = set(first["_id"]) | {"football"}
    shown = cur[cur["_id"].isin(ids) | (cur["side"] == "ball")]
    trails = df[(df["frameId"] <= fid) & df["_id"].isin(ids) & (df["side"] != "ball")]
    for (_, side), g in trails.groupby(["_id", "side"]):
        xs, ys = fld.xy(g["x"].values, g["y"].values)
        ax.plot(xs, ys, color=style.OFFENSE if side == "off" else style.DEFENSE, lw=0.9, alpha=0.4, zorder=3)
    ppy = fld.pts_per_yard()
    for _, r in shown.iterrows():
        x, y = (float(v) for v in fld.xy(r["x"], r["y"]))
        if r["side"] == "ball":
            ax.add_patch(Ellipse((x, y + 0.45), 0.7, 0.42, fc=style.BALL, ec="white", lw=0.5, zorder=9))
            continue
        lab = str(r.get("label", "") or "")
        if r["side"] == "off":
            ax.add_patch(Circle((x, y), MARK_R, fc=style.OFFENSE, ec="white", lw=0.6, zorder=8))
            tc = "white"
        else:
            ax.add_patch(RegularPolygon((x, y), 4, radius=MARK_R * 1.3, orientation=np.pi / 4,
                                        fc=style.DEFENSE_TINT, ec=style.DEFENSE, lw=1.0, zorder=8))
            tc = style.INK
        fs = max(4.0, min(8.0, ppy * (0.85 if len(lab) <= 1 else 0.62)))
        ax.text(x, y, lab, ha="center", va="center", fontsize=fs, color=tc, fontweight="bold", zorder=10)
    for key, col in rings:
        r = cur[cur["displayName"] == key].iloc[0]
        x, y = fld.xy(r["x"], r["y"])
        ax.add_patch(Circle((float(x), float(y)), ring_r, fc="none", ec=col, lw=1.6, zorder=7))
    for patch in ax.patches:
        patch.set_clip_on(True)
    return fld


def strip(moments, lateral, window, notes=None, rings=(), ncols=2, width_in=5.2, after=None):
    """Numbered frame strip. `moments` is a list of (play, t, tag): several plays may share one strip,
    which is how two versions of the same play (same start, two endings) are shown in print."""
    cache = {}
    nrows = int(np.ceil(len(moments) / ncols))
    pw = width_in / ncols
    span_w, span_d = lateral[1] - lateral[0], window[1] - window[0]
    fig, axes = plt.subplots(nrows, ncols, squeeze=False,
                             figsize=(width_in, nrows * (pw * span_d / span_w + (0.62 if notes else 0.25))))
    for ax in axes.flat[len(moments):]:
        ax.axis("off")
    for i, (ax, (play, t, tag)) in enumerate(zip(axes.flat, moments)):
        if id(play) not in cache:
            cache[id(play)] = tracking(play)
        fld = panel(ax, play, cache[id(play)], t, lateral, window, rings)
        if after:
            after(fld, play, t, i)
        lab = "snap" if abs(t) < 1e-6 else f"{t:+.1f} s"
        ax.set_title(f"{i + 1}.  {lab}" + (f"   {tag}" if tag else ""), fontsize=8.3, color=style.INK_2, loc="left")
        if notes:
            ax.text(0.5, -0.03, notes[i], transform=ax.transAxes, ha="center", va="top",
                    fontsize=7.1, color=style.INK)
    fig.tight_layout(h_pad=1.3 if notes else 0.6, w_pad=0.6)
    return fig


def video(segments, lateral, window, rings=(), width_in=4.6, after=None):
    """Web version: each (play, tag, [(t, note), ...]) segment played in turn, notes as captions."""
    import shutil
    from matplotlib import animation
    from IPython.display import HTML, display
    span_w, span_d = lateral[1] - lateral[0], window[1] - window[0]
    fig, ax = plt.subplots(figsize=(width_in, width_in * span_d / span_w + 0.45))
    frames = []
    for play, tag, notes in segments:
        df = tracking(play)
        tmap = df.groupby("frameId")["time"].first()
        frames += [(play, df, float(tmap[f]), tag, notes) for f in sorted(df["frameId"].unique())]

    def update(k):
        play, df, t, tag, notes = frames[k]
        ax.clear()
        fld = panel(ax, play, df, t, lateral, window, rings)
        if after:
            after(fld, play, t, -1)
        txt = ("snap" if abs(t) < 0.05 else f"{t:+.1f} s") + (f"  {tag}" if tag else "")
        cur = [n for tt, n in notes if tt <= t + 1e-6]
        ax.set_title(txt + (("\n" + cur[-1].replace("\n", " ")) if cur else ""), fontsize=8.5, color=style.INK,
                     loc="left")
        return []

    anim = animation.FuncAnimation(fig, update, frames=range(len(frames)), interval=100)
    html = (anim.to_html5_video(embed_limit=40).replace("<video ", '<video style="max-width:100%;height:auto" ')
            if shutil.which("ffmpeg") else anim.to_jshtml(default_mode="once"))
    plt.close(fig)
    display(HTML(html))


def animation_or_strip(moments, notes, lateral, window, rings=(), after=None, ncols=2, width_in=5.2):
    """Video on the website; a numbered, captioned frame strip in the PDF."""
    if pdf_build():
        strip(moments, lateral, window, notes=notes, rings=rings, ncols=ncols, width_in=width_in, after=after)
        plt.show()
        return
    segs = []
    for play, t, tag in moments:
        if not segs or segs[-1][0] is not play:
            segs.append((play, tag, []))
    for (play, t, tag), n in zip(moments, notes):
        for s in segs:
            if s[0] is play:
                s[2].append((t, n))
    video(segs, lateral, window, rings=rings, after=after)

First-and-10, early in the third quarter. The offense runs power to the right: a guard pulls from the left side, the fullback races toward the outermost defender on the line on the right, and for a split second there is a hole outside the tight end that looks big enough to drive a truck through. Then the end man does something that looks like a mistake. Instead of standing up to the fullback, that end man throws himself underneath him, toward the inside, and the two of them go down in a heap right where the hole was supposed to be. The pulling guard has nowhere to go. The running back bounces outside, finds green grass for a stride, and is met by a safety who was twelve yards deep when the ball was snapped. Gain of two. The analyst says, “Great fit by the defense.” Nobody on the defense made a spectacular play. Nobody beat a block. So what, exactly, was great? This chapter is the answer: a run defense is not eleven men chasing the ball, but eleven assignments that add up, and the end who “lost” that collision was the most important part of the sum.

You’ll be able to:

NoteYou’ll need

How to read the diagrams. Offense is blue circles, defense orange squares, and left and right always mean the offense’s left and right. On offense, C is the center (the other four linemen are unlettered), Q the quarterback, R the running back, F the fullback, Y the tight end, and X, Z and H receivers. Defensive linemen are labelled by their technique number (5, 3, 1), S, M and W are the Sam, Mike and Will linebackers, $ is the nickel back, CB a cornerback, and FS and SS the free and strong safeties. Blue lines ending in a short bar are blocks; orange arrows are where defenders go; the thick dark-blue arrow is the ball carrier. In the frame strips, faint lines are where each player has been. Rings keep one meaning all chapter: purple is the force (or the plus-one), green the alley player or another free fitter, orange the end man (the spill or box player) or another defender whose technique the figure is about, and gray the offensive player to watch, usually the ball carrier. Where the Sam (S) stands on the line beside a 5-technique (5), he wears the orange ring, so the two never get confused.

What a run fit is

Start with the offense, because run defense only makes sense as an answer to it. Every run play in Part 3 is built around one of two ideas. Either it creates a crease the defense did not expect (zone’s moving wall and cutback), or it creates an extra blocker at one spot (power’s pulling guard, the fullback on an iso, the quarterback’s read on the option). Both ideas attack the same weakness: a defender who is not where his teammates think he is.

So the defense’s first answer is not a technique or a tackle. It is a plan. A run fit is the defense’s plan for which defender takes which gap or job against a run, and also the act of carrying it out: each defender getting to his gap after the snap, on the correct side of whoever is blocking him. Coaches use the word both ways. “Our fits were bad” means people went to the wrong places; “he fit it perfectly” means one player arrived in his gap at the right moment, on the right shoulder.

The principle underneath every fit has a name of its own: gap integrity. Every gap the offense can run through has exactly one defender responsible for it, and each defender stays in his gap until the ball shows him where it is going. “Exactly one” cuts both ways. A gap with nobody in it is an obvious problem: that is where the long run goes. A gap with two defenders in it is the same problem in disguise, because the defense only has so many players. If two defenders are in the B gap, some other gap is empty, and a good running back will find it.

You met the counting in Defensive Line Play: against a formation with one tight end there are seven gaps along the line (two A gaps either side of the center, two B gaps, two C gaps, and a D gap outside the tight end), and a one-gap defense puts one defender in charge of each. That count was the static version. Run fits are what happens when the count starts moving, and it moves for three reasons:

  1. Blockers carry gaps with them. A gap is not a patch of grass; it is the space between two blockers. When the tight end blocks down on the man inside him, the C gap slides inward with him, and a new space opens outside.
  2. Backs add gaps. A fullback who runs to the line, or a guard who pulls, is one more blocker at one spot, and the space beside him is one more gap. Coaches say every back in the backfield can add a gap. Power’s whole point is to create a gap at the point of attack that the defense did not have a man for before the snap.
  3. The defense moves too. Linemen slant, linebackers blitz, safeties rotate. Each of those moves takes a defender out of one gap and puts him in another, so somebody else has to inherit the gap he left.

A fit is the defense’s way of keeping the count right while all of that happens. Before the snap, each defender knows his gap. After it, each knows how his gap changes when he sees a particular block: if the tackle in front of me blocks down, my gap is outside; if the guard pulls, the linebacker behind me fast-flows and I inherit his. The names you will learn in this chapter (force, spill, box, alley) are the vocabulary of those changes.

ImportantWhy it exists

A defense has eleven players and the offense knows where the ball is going; the defense does not. Run fits exist so that the defense does not need to know. If every gap has an owner and every owner knows how his gap moves when the blocking changes, the ball can go anywhere and somebody is waiting. The price is discipline. A fit only works if all eleven players do their job instead of chasing the ball, which means trusting the man next to you. The most talented player on the field can wreck a defense by “making a play” outside his gap and leaving it empty.

NoteMadden vs. real life

In Madden, the move every user learns is to grab the safety, wait for the handoff and sprint at the ball carrier. It works because the computer plays the other ten defenders’ gaps perfectly. In real football, a player who leaves his gap to make a play is the most common reason for a long run, and coaches grade it as a missed assignment even when he makes the tackle. When you see a 60-yard run on a broadcast, rewind to the snap and look for the defender who ran to the wrong side of a block. It is rarely the man who missed the tackle at the end.

Force: who turns the ball back inside

Every run has an inside and an outside, and the outside is where the defense has fewest bodies. So before anyone talks about gaps, the defense names one player on each side of the ball whose job is the outside edge. He is the force defender, or “the force”: the defender responsible for keeping the ball carrier from getting outside him on a run to his side and for turning (forcing) the ball back inside, toward the teammates who are chasing it. He does not have to make the tackle. He has to make the runner change direction, back into the crowd.

You have met two cousins of this idea. In Defensive Line Play, to set the edge was a technique: the outermost defender on the line takes on a blocker with his outside arm free so the run can’t get outside him. Contain was a rule about the quarterback escaping the pocket or running a bootleg. Force is a role. It belongs to whichever defender the call assigns, and the call changes from play to play. Sometimes the force is the defensive end, setting the edge exactly as 05-01 drew it. Often it is an outside linebacker, a nickel back or a safety a few yards outside the end. In some coverages it is a cornerback.

Why would a cornerback be the force? Because the coverage decides who is free. A defender who has a deep zone to protect cannot also come up to the line to turn a run inside; a defender with a short zone, or with no zone at all, can. That is why the first question to ask about a run defense is not “who’s in the box?” but “what are the safeties and corners doing?” Two common answers, which you will see drawn in full in the coverage chapters:

  • Safety force (Cover 3, “sky”). Cover 3 splits the deep field into three zones, the deep thirds: one for each corner and the middle one for the free safety. The other safety is spare, so he comes down to the strong side, outside the tight end, and becomes the force. The corners are deep, so they cannot be. This is the eighth man in the box. Coaches call it a sky rotation: s for the safety who comes down.
  • Corner force (Cover 2, “cloud”). Cover 2 keeps both safeties deep, each guarding a deep half of the field. The corners have no deep zone, so they sit at about five yards, a step outside the widest receiver, and come up to force the run. This short corner is the hard corner of 06-04, and coaches call his side a cloud side: c for the corner who stays short.

The words describe who comes down, not the coverage number, so don’t equate cloud with Cover 2. A Cover 3 defense can also “cloud” one side (the corner stays short and a safety runs to the deep third behind him), and in a buzz rotation the Cover 3 safety comes down inside, as the alley player, and the outside linebacker or nickel back already standing out there is the force. Cover 3 draws all three rotations.

Who stands just inside the force is the next question, and it is the subject of the next section, but you can see both answers at once in Figure 32.1.

Show the Python
fig, axes = plt.subplots(1, 2, figsize=(6.6, 3.25))
for ax, (ttl, dfn, force, alley, fnote, anote) in zip(axes, [
        ("Cover 3 (sky): safety force",
         over_front() + [D("SS", "SS", 6.5, 9.5, "SS"), D("FS", "FS", 13.0, 0.5, "FS"),
                         D("RCB", "CB", 7.5, 15.0, "CB")], "SS", "FS",
         "SS: force", "FS: alley"),
        ("Cover 2 (cloud): corner force",
         over_front() + [D("SS", "SS", 12.5, 9.0, "SS"), D("FS", "FS", 12.5, -9.0, "FS"),
                         D("RCB", "CB", 4.5, 15.8, "CB")], "RCB", "SS",
         "CB: force", "SS: alley")]):
    p = Play(i_form(), dfn, los=35, to_go=None)
    p.highlight(force, color=FORCE_RING); p.highlight(alley, color=ALLEY_RING); p.highlight("SAM", color=WATCH_RING)
    fp, ap = p.players[force], p.players[alley]
    go_to(p, force, (2.4, 11.4), "path", speed=4.5)
    go_to(p, alley, (5.0, 7.2), "path", speed=4.5)
    fl = draw(p, ax=ax, lateral=(-11.0, 18.0), window=(-8.5, 15.5), title=False)
    lane(fl, p, 7.4, 13.2, -0.3, 6.0, color=GREEN, alpha=0.07)
    say(fl, p, 3.3, 11.4 if force == "SS" else 9.0, "the alley", color=GREEN, fontsize=6.6, weight="bold")
    point_to(fl, p, (fp.d + (2.6 if force == "SS" else -3.4), fp.w + (3.0 if force == "SS" else -1.4)),
             (fp.d, fp.w), fnote, color=PURPLE, fontsize=6.8, weight="bold")
    point_to(fl, p, (ap.d - 1.2, ap.w - 4.4 if alley == "FS" else ap.w - 6.0), (ap.d, ap.w), anote, color=GREEN, fontsize=6.8, weight="bold")
    subtitle(ax, ttl)
fig.tight_layout(w_pad=0.6)
plt.show()
Figure 32.1: Force and alley depend on the coverage. Same power-side picture, run to the right, with the Sam (orange ring) walked up as the end man. Left, Cover 3 ‘sky’: the strong safety has come down outside the tight end and is the force (purple ring), coming up outside-in; the free safety comes down from the deep middle to fill the alley (green ring, green lane). Right, Cover 2 ‘cloud’: both safeties stay deep, the cornerback squats at five yards and is the force, and the safety on that side fills the alley from his deep half. The man outside forces; the man inside him fills the alley.

The force has a hard job, and the technique he uses is mostly patience. He comes up outside-in: he approaches the ball from outside its path, keeping his inside shoulder toward the runner and his outside arm free, never letting the runner’s helmet get to his outside. Coaches often name two speeds of it. Hard force is fast and tight: the squatting Cover 2 corner attacks the line and meets the ball close to it. Soft force is slower and deeper: a safety coming from a deep zone keeps his outside leverage and gives a little ground, accepting a few yards to be sure nothing gets outside him. Either way the failures are the same. Come up too fast and too far inside, and a back with any speed simply runs around him. Come up too slowly, and the back turns upfield inside him for seven yards before anyone arrives. A good force player is the defense’s answer to two of the offense’s most dangerous plays: the outside run that wins the corner, and the bounce, which is a run that was designed to go inside and ends up outside. The bounce is the force’s specialty, and it is where the next idea comes in.

CautionCommon misconception

“The defensive end is always responsible for the outside.” Sometimes he is, and then he sets the edge. But in many calls the end is told to do the opposite: take on blocks inside and let somebody else have the outside. (Keep two names apart here. The defensive end is a position, the lineman at the end of the front. The end man is whoever is outermost on the line on that side; with an outside linebacker walked up beside the end, the linebacker is the end man, not the end.) Whether the end is the force or not is decided by the call and the coverage, and you can often tell before the snap. If a safety or a corner is standing five to seven yards deep just outside the tight end, the end probably isn’t the force.

Spill or box: two ways to meet a kick-out

Now go back to the play this chapter opened with. Power’s kick-out block, from Gap and Power Runs, asks a question of the end man on the line of scrimmage, the outermost defender on the line on that side. Here he is the Sam linebacker, walked up on the line outside the tight end (a wide 9; Even Fronts drew the 4-3 Over’s Sam off the ball, and walking him up is a common variation), not the 5-technique defensive end inside him. The question: a fullback is coming at you from the inside, and a pulling guard and the running back are right behind him. What do you do?

You have met both answers already, from the offense’s side in 03-03 (kick or log) and from the lineman’s side in Defensive Line Play (the wrong arm). Here is the full version, because the choice between them is a team decision, not one player’s.

Spill. The defender attacks the blocker’s inside half with a wrong arm, his outside shoulder and arm thrown across and under the blocker toward the hole. He is not trying to win. He is trying to make a pile in the hole: his body, the fullback’s body, and soon the pulling guard, who arrives to find his lane full. The running back, who was following that guard, has nowhere to go inside, so the ball spills outside, sideways along the line.

Box technique, also called squeeze. The defender keeps his outside arm free, meets the blocker with his inside shoulder, and drives him back inside, so the hole gets smaller and smaller. He is “boxing” the ball in: it cannot get outside him, so it has to stay inside, where the linebackers are filling. (Don’t confuse box technique with the box, the area near the ball where defenders are counted. The words are unrelated; football just reuses them.)1 Coaches also say squeeze for the thing an end does a moment earlier, closing down the line behind a tackle’s or tight end’s down block (05-01). The two usually come in sequence: squeeze the down block, then box or spill the kick-out.

The two techniques send the ball to opposite places, and that is the whole point of choosing between them. A defender who spills is promising that someone is waiting outside. A defender who boxes is promising that someone is waiting inside. In Figure 32.2 the same power play meets both.

Show the Python
def kick_play(call):
    """Power right with the play side only; call = 'spill' or 'box' for the end man (the Sam)."""
    off = [q for q in i_form(wrs=False, puller="LG")]
    dfn = over_front() + [D("SS", "SS", 6.5, 10.0, "SS")]
    p = Play(off, dfn, los=35, to_go=None)
    go_to(p, "Y", (0.4, 3.9), via=[(-0.3, 4.6)])                         # down block on the 5...
    go_to(p, "SE", (1.5, 3.4), "path", speed=2.0)                       # ...who squeezes inside with it
    go_to(p, "RT", (0.4, 2.6), via=[(-0.3, 3.0)])
    go_to(p, "RG", (3.0, -1.2), via=[(0.05, 2.0)])
    go_to(p, "C", (0.35, -0.3), via=[(-0.45, -0.15)])
    go_to(p, "LT", (-1.9, -3.7), via=[(-1.0, -2.6)])
    p.handoff("RB", t=0.75)
    go_to(p, "QB", (-3.4, -1.8), "path", speed=3.0)
    pull_via = [(-1.3, -1.2), (-1.8, 0.4), (-1.8, 3.4), (-0.7, 4.6)]   # flat, skimming the down blockers' heels
    if call == "spill":
        go_to(p, "SAM", (-1.0, 6.0), "path", speed=2.6)                     # attacks the F's inside half
        go_to(p, "FB", (-1.4, 6.8), via=[(-3.6, 5.0)], speed=6.5)           # meets him in the backfield
        go_to(p, "LG", (1.4, 5.0), "pull", speed=6.5, via=pull_via)
        go_to(p, "MIKE", (1.8, 7.8), "path", speed=4.3, via=[(3.4, 3.6)])  # fast flow: around the pile
        go_to(p, "RB", (2.0, 10.4), "run", speed=5.5, delay=0.2,
              via=[(-5.7, 1.2), (-3.4, 4.2), (-2.4, 7.8), (-0.2, 9.8)])
        go_to(p, "SS", (2.5, 11.2), "path", speed=2.6, via=[(4.4, 10.8)])
    else:
        go_to(p, "SAM", (0.4, 6.3), "path", speed=2.4)                      # squeezes down, outside arm free
        go_to(p, "FB", (-0.5, 5.6), via=[(-3.6, 5.0)], speed=6.5)           # kick-out meets him at the line
        go_to(p, "LG", (1.1, 5.4), "pull", speed=6.5, via=pull_via)
        go_to(p, "MIKE", (2.2, 4.9), "path", speed=4.2, via=[(3.4, 3.6)])   # fills the hole, meets the puller
        go_to(p, "RB", (0.0, 4.6), "run", speed=5.5, delay=0.2, via=[(-5.7, 1.2), (-3.4, 4.2), (-1.4, 4.5)])
        go_to(p, "SS", (3.6, 9.4), "path", speed=2.2)                       # stays outside: nothing out here
    return p


SPILL, BOX = kick_play("spill"), kick_play("box")


def hole_marks(fld, play, t, i):
    """Point at the hole: full of bodies after the spill, about a yard wide after the box."""
    if t < 1.0 or t > 1.6:
        return
    if play is BOX:
        point_to(fld, play, (-4.2, 9.6), (0.2, 5.0), "hole: ~1 yd", color=style.INK, fontsize=6.6, weight="bold",
                 shrink=3)
    else:
        point_to(fld, play, (-4.6, 10.0), (-1.0, 6.2), "hole: full", color=style.INK, fontsize=6.6, weight="bold",
                 shrink=9)


animation_or_strip(
    [(SPILL, 0.6, "spill"), (SPILL, 1.3, "spill"), (SPILL, 2.6, "spill"),
     (BOX, 0.6, "box"), (BOX, 1.3, "box"), (BOX, 1.8, "box")],
    ["SPILL: the S attacks the F's\ninside half, in the backfield",
     "the pile fills the hole;\nthe G has no lane",
     "ball bounces outside,\nwhere the SS (force) meets it",
     "BOX: the S squeezes down,\noutside arm free",
     "the F kicks him at the line;\nthe hole shrinks",
     "ball stays inside, into\nthe M filling the hole"],
    lateral=(-3.0, 13.5), window=(-9.0, 8.5), ncols=3, width_in=6.5,
    rings=(("SAM", WATCH_RING), ("RB", BALL_RING), ("SS", FORCE_RING)), after=hole_marks)
Figure 32.2: Spill or box: the same power play against two techniques by the end man (the Sam, orange ring; the running back has the gray ring, the strong safety, the force, the purple ring; G is the pulling guard). Both rows start from the same pre-snap picture (the left half of the force-and-alley figure) and show the same moments after the snap. Top row, spill: the Sam attacks the fullback’s inside half in the backfield, the pile fills the hole and leaves the pulling guard no lane, and the ball bounces outside to the strong safety, with the Mike running around the pile behind him. Bottom row, box: the Sam squeezes down with his outside arm free and takes the kick-out at the line, the hole shrinks to about a yard, and the Mike fills it and meets the pulling guard there. Each technique sends the ball to a different teammate.

Follow the end man, ringed in orange, through both rows. In the top row he spills: he attacks the fullback before the fullback can get to him, takes him down in the backfield, and the pulling guard (G) turns up into a lane already full of bodies. The back has nowhere to go but out, and out is where the strong safety, the force, is waiting, with the Mike running around the outside edge of the pile behind him. In the bottom row he boxes: he steps down, keeps his outside arm free and lets the fullback hit him at the line of scrimmage. The hole the play designed is still there, but it is about a yard wide instead of three (the middle frame), and the Mike fills it downhill and meets the pulling guard right in it. The back has nowhere to go but straight into the collision.

Why choose one or the other?

Both techniques work. Both fail. The difference is how they fail, and a defense picks the failure it can live with.

Spill sends the ball to speed. A run that bounces sideways is running at the slowest angle in football: it gains no yards while it moves, and every defender on the field can chase it. Defenses with fast linebackers and safeties love to spill, because they would rather tackle a back in space with three pursuers than in a crowded hole with one. Spill also attacks the heart of a gap scheme. Power and counter depend on the puller turning up into a clean hole; take the hole away and the play’s best blocker becomes a spectator. The risk is the outside. A spilled ball is going exactly where the defense has fewest bodies, and if the force is late, blocked or out of position, the back is around the corner with nobody between him and the end zone.

Box keeps the ball in the crowd. Boxing keeps everything inside, where the big bodies are, and it is simpler for the defenders outside: the force can stay outside and wait, because nothing is supposed to get to him. The risk is inside. A boxing end who gets driven off the ball (the kick-out does its job) leaves a hole wider than the one the play designed, and if the linebacker filling it is a step late or gets caught by the puller, the back runs through the middle of the defense untouched.

The offense has an answer to each. Spill is exactly the picture Gap and Power Runs called log: when the end man gets inside the kick-out, the puller stops trying to kick him out, takes his outside shoulder instead and seals him in with a log block, and the back bounces outside the log. So a spill call is a dare. The defense is inviting the offense to bounce the ball, because it has a man waiting outside, and the whole bet rides on the force. If he is there, the logged bounce runs into him and gets turned back toward the pursuit. If he is late or blocked, the log has opened the edge. Against box, the offense’s answer is simply the play as drawn: the kick-out block is the right block, and the back cuts up inside it, so the defense is betting on the linebacker who fills that hole.

A common way to organize all this, though staffs differ, is a pattern coaches sometimes call spill inside, force outside: the players closest to the ball, linemen and inside linebackers, spill anything coming at them, and the outermost defender on each side keeps everything inside him, so that every spilled ball runs into a man who stops it from getting further out. In the top row of Figure 32.2, that is exactly the shape: the Sam spills, and the strong safety, the force, keeps the ball inside him. The ball gets squeezed between them. Many spill defenses spill at two levels: the end man spills the fullback, and the play-side linebacker spills the puller too, attacking his inside half instead of running around the pile; then the play-side end, fighting back across the tight end’s down block, owns the gap inside the pile. Other defenses ask their end man to box and their linebackers to spill the puller, and some change the call by formation or by opponent. What matters for you watching on Sunday is the promise each technique makes. When the end man wrong-arms a blocker, look outside for the man who has to be there.

NoteMadden vs. real life

In Madden you pick the defense and every player simply knows his job. In real football, spill or box, and who is the force, travel with the call. The defensive coordinator’s call reaches one player through the radio in his helmet, the green dot of What a Play Really Is, usually a linebacker (see Linebackers), who repeats it to the other ten. Many defenses build the run fit into the call itself, so that a coverage word also says which safety comes down and whether the edge spills or boxes. Then, at the line, the Mike and the safeties adjust it to the formation they see, shouting a strength call (“Strong right!”, from Even Fronts), a “crack!” warning when a receiver cuts his split, or a check that changes the spill player, until the snap. The fit that eleven players carry out is finished at the line, in the last seconds before the snap, by the players who can see the offense.

TipWatch for it

The tell is the end man’s first contact. If he dives under the kick-out block toward the ball, it is a spill, and the run should bounce: watch for the force. If he stays square, outside arm free, and takes the block on his inside shoulder, it is a box, and the run should stay inside: watch the linebackers fill. When a broadcast shows a power run from the end-zone camera, the pile in the hole after a spill is impossible to miss.

The alley player

Spill a ball outside and it does not go straight to the force. It goes first into the space between the box and the force, a lane a few yards wide just outside the last defender on the line. Coaches call that lane the alley, and the defender responsible for it is the alley player: the man who fills the gap between the force player and the box, meeting a run that has bounced outside the box but not outside the force.

Look back at Figure 32.1. In the Cover 3 picture the strong safety is the force and the free safety, coming down from the deep middle, is the alley player; in some calls it is the Mike linebacker, running around the outside edge of the pile. In the Cover 2 picture the cornerback is the force and the safety on that side is the alley player, coming down from his deep half. In quarters (Quarters and Match), a fast-growing two-high coverage,2 the outside linebacker or nickel back is usually the force and the safety is the alley player. Names and exact assignments differ by staff.3 The geometry does not. Every sound fit has, on each side of the ball, an outside man who forces and a man inside him who fills the alley.

The two come at the ball from opposite sides, and that is the point. The force comes outside-in. The alley player comes inside-out: he approaches from inside the ball’s path, a step behind it, keeping the runner on his outside shoulder, the same leverage a linebacker keeps when he flows (Linebackers). A runner caught between them can’t cut back inside the alley player and can’t get outside the force, so the only way out is into the narrowing lane between two tacklers.

Why does the alley player usually come from the secondary? Because he has to come from outside the blocks. The linebackers start in the box, where blockers can reach them: a pulling guard leads up on the Mike, a tight end climbs to the Will. A safety eight or twelve yards deep starts where no lineman can get to him before he reads the play.

How does he know it’s a run, and in time? He reads a key, just as a linebacker does, usually the nearest tight end or offensive tackle. Coaches call it high hat, low hat. A blocker who fires out low and forward, or a guard who pulls, is a low hat: run, so come down. A blocker who pops up tall and sets back to protect is a high hat: pass, so play the deep zone.4 The read takes a fraction of a second, and it is exactly what the offense attacks. Play-action is built to show low hats and a handoff fake, pull the alley safety forward a few steps, and send a receiver into the deep zone he just left. That is what the alley player costs: a safety filling the alley is not covering the zone he started in.

The fit chart: eleven defenders against power

Now put the pieces together for one play. Here is the same power play, right, against a 4-3 Over with a single-high safety, the strong safety down outside the tight end, and the end man (the Sam, walked up on the line) told to spill. A coach would draw this as a fit chart: the play, with every defender’s job written next to him. Figure 32.3 is the picture and the table under it is the chart. Read the table with the picture, one number at a time. The row of gap letters under the backfield is the answer to “who owns each gap?”: under each gap is the number of the defender who owns it once power has shown itself.

Show the Python
def power_blocks(p):
    """Power right, as drawn in Gap and Power Runs: down blocks by the Y and the RT (the RG helps on the 3,
    then climbs to the Will), the C blocks back, the LT hinges, the LG pulls flat, the F kicks out the end man."""
    go_to(p, "Y", (0.5, 4.3), via=[(-0.3, 4.75)])
    go_to(p, "RT", (0.4, 2.8), via=[(-0.3, 3.05)])
    go_to(p, "RG", (3.4, -1.0), via=[(0.05, 2.0)])
    go_to(p, "C", (0.35, -0.3), via=[(-0.45, -0.15)])
    go_to(p, "LT", (-1.9, -3.7), via=[(-1.0, -2.6)])
    go_to(p, "LG", (2.0, 5.5), "pull", via=[(-1.4, -1.4), (-1.9, 0.4), (-1.9, 3.6), (-0.8, 4.9)])
    go_to(p, "FB", (-0.6, 6.2), via=[(-3.6, 4.8)], speed=5.0)
    return p


def badge(fld, p, d, w, n, color=style.DEFENSE_DARK, fontsize=6.6):
    """A numbered tag that ties a defender to a row of the fit-chart table."""
    x, y = _P(fld, p, d, w)
    fld.ax.text(float(x), float(y), str(n), fontsize=fontsize, color="white", fontweight="bold", ha="center",
                va="center", zorder=13, bbox=dict(boxstyle="circle,pad=0.18", fc=color, ec="white", lw=0.6))


# (defender, offset in d, offset in w) for the numbered tags, in the order of the fit-chart table
FIT_BADGES = [("WE", 0.0, -1.7), ("NT", 0.0, -1.6), ("DT", 1.5, -0.3), ("SE", 1.5, 0.15), ("SAM", 2.0, 1.2),
              ("MIKE", 1.4, 0.0), ("WILL", 0.0, -1.7), ("SS", 0.0, 1.8), ("FS", 0.0, -1.9), ("RCB", 0.0, 1.8),
              ("LCB", 0.0, 1.8)]

# the gap row under the backfield: (width, gap letter, owner numbers after the snap)
GAP_ROW = [(-4.0, "C", "1"), (-2.4, "B", "7"), (-0.8, "A", "2"), (0.8, "A", "3"), (2.4, "B", "3"),
           (4.0, "C", "4"), (5.6, "D", "5")]
OUTSIDE_ROW = [(7.9, "bounce", "6"), (10.5, "alley", "9"), (13.1, "edge", "8")]


def sky_defense():
    """4-3 Over, single-high (Cover 3 'sky'): the strong safety down outside the Sam, the free safety in the
    deep middle, the corners deep."""
    return over_front() + [D("SS", "SS", 6.5, 9.5, "SS"), D("FS", "FS", 13.0, 0.5, "FS"),
                           D("LCB", "CB", 7.5, -15.0, "CB"), D("RCB", "CB", 7.5, 15.0, "CB")]


p = Play(i_form(puller="LG"), sky_defense(), los=35, to_go=None,
         title="An 11-man fit chart: power right vs a 4-3 Over, Cover 3")
power_blocks(p)
go_to(p, "RB", (2.4, 9.3), "run", via=[(-5.7, 1.2), (-3.2, 4.4), (-1.6, 7.0)])
# the defense's fits (orange arrows): where each man goes to own his piece of the field
go_to(p, "SAM", (-0.4, 6.0), "path", speed=4.0)           # spill: wrong-arm the fullback
go_to(p, "SS", (2.9, 9.6), "path", speed=4.5)             # force
go_to(p, "MIKE", (2.6, 6.4), "path", speed=4.5)           # fast flow outside, around the pile
go_to(p, "WILL", (3.4, -1.9), "path", speed=3.0)          # slow flow: backside B gap, the cutback
go_to(p, "FS", (8.0, 6.0), "path", speed=4.5)             # alley, inside-out
go_to(p, "WE", (-2.6, -2.6), "path", speed=4.0, via=[(0.0, -4.6)])   # chase flat behind the line, eyes on the boot
p.highlight("SAM", color=WATCH_RING); p.highlight("SS", color=FORCE_RING); p.highlight("FS", color=ALLEY_RING)
f = draw(p, width_in=6.4, lateral=(-18.0, 18.5), window=(-12.6, 16.0))
dashed(f, p, [(-5.7, 1.2), (-3.4, 4.0), (-1.2, 5.1), (1.4, 5.2)], color=style.OFFENSE, lw=1.3)
for n, (key, dd, dw) in enumerate(FIT_BADGES, start=1):
    q = p.players[key]
    badge(f, p, q.d + dd, q.w + dw, n)
for w, g, own in GAP_ROW:
    gap_tag(f, p, -9.5, w, g, fontsize=6.6)
    badge(f, p, -10.9, w, own, fontsize=6.0)
for w, g, own in OUTSIDE_ROW:
    gap_tag(f, p, -9.5, w, g, color=style.INK_2, fontsize=6.0)
    badge(f, p, -10.9, w, own, fontsize=6.0)
say(f, p, -9.5, -9.6, "gaps after the snap", fontsize=6.4, color=GREEN, weight="bold")
say(f, p, -10.9, -9.6, "owner (table row)", fontsize=6.4)
plt.show()
Figure 32.3: An eleven-man fit chart against power right (the play of Gap and Power Runs), against a 4-3 Over with the Sam walked up on the line, a single-high safety and the strong safety down. Blue: the blocks and the pulling guard (G); the thick blue arrow is the running back’s path after the spill (the bounce), and the dashed blue line is the path power was designed for, inside the kick-out. Orange arrows: where the defenders who move go. Rings: the spill player (orange), the force (purple) and the alley player (green). Bottom row: the gaps along the line and, under each, the number of the defender who owns it after the snap; outside them, the bounce lane, the alley and the edge. The numbers match the table below; every defender, including both cornerbacks, has a job.
# Defender Gap or area Job against power right Why it matters
1 Backside end (5-technique, left) Backside C, then the chase Unblocked. Squeeze flat down the line and chase; check the quarterback for a bootleg or keeper first. Power leaves him free on purpose: the left tackle’s hinge only closes the gap the pulling guard left. He is too far away to stop the play, so his job is the cutback, the boot and the reverse.
2 Nose (1-technique, left) Backside A Hold the backside A gap against the center’s back block. If he gets pushed out of it, the cutback has a lane right up the middle.
3 Defensive tackle (3-technique, right) Play-side A and B Anchor against the double team: give no ground, keep both blockers busy. The double team and the center’s back block squash the two gaps into one, and he holds it. Every second he holds two blockers is a second the right guard can’t climb to the Will.
4 Play-side end (5-technique, right) Play-side C Fight the tight end’s down block (squeeze), stay on the blocker’s outside hip, and own the gap inside the pile. If he is washed inside, the hole doubles in size.
5 Sam (end man, right) D, the hole Spill: wrong-arm the fullback’s kick-out, as deep in the backfield as he can. The pile he makes is the wall that sends the ball outside.
6 Mike The bounce lane Fast flow: run around the outside edge of the pile, ready for the bounce. He is the second man outside. If the puller catches him, the safety has to be right.
7 Will Backside B, then fold Slow flow: own the backside B gap and the cutback first; once the ball is past, fold over the double team toward the play-side A gap the Mike left, and pursue. The right guard’s climb is aimed at him. If he over-runs the play, the cutback is open.
8 Strong safety The edge Force: come down outside-in, keep the ball inside him, turn the bounce back. The spill only works because he is there.
9 Free safety The alley Alley: come down from the deep middle, inside-out, into the lane between the pile and the force. Third man to the ball, and the last one between a bounce and a long run.
10 Right cornerback Deep third, or the edge Deep third: read the receiver in front of him; if the Z blocks in on the safety (a crack block), he replaces the safety as the force. The crack-and-replace rule keeps the edge from going empty when the offense blocks the force.
11 Left cornerback Backside deep third Deep third on the backside: no deep pass behind him, then the last defender on any cutback that breaks. Somebody has to stay home on a play-action pass.

This is a typical way to fit the play, not one team’s playbook: defenses vary the spill and box calls, who flows where, and which safety comes down.

Three things are worth noticing.

Everybody has a job, including the players far from the ball. The left cornerback is fifteen yards from the play and still has an assignment, and if he leaves it to chase the run, a play-action pass to the X receiver is a touchdown. Fits are eleven-man plans, which is why defensive coaches say a run defense is only as good as its worst fit.

The defense counts, and so does the offense. Power brought seven blockers to the party (five linemen, the tight end and the fullback). The defense brought eight defenders into and around the box (four linemen, three linebackers and the strong safety), plus a free safety who can arrive late. Count who is left unblocked, though, and you find two: the backside end and the strong safety. That is not a contradiction. The offense chooses which defender to leave free, and power, as Gap and Power Runs showed, leaves the one farthest from the hole: the backside end, who has to chase down the line behind a wall of bodies, while the left tackle’s hinge only closes the gap the pulling guard left. So the free defender who matters is the one at the point of attack, and that is where the defense spends its eighth man: as the force, outside the play, exactly where a spilled ball ends up. The plus-one, below, gives that man a name. The fit chart and the box count are the same idea seen from two sides.

Gaps move, and the fits move with them. Before the snap, the Mike was over the right A gap. After the snap, the right A and B gaps have become one crowded space: the 3-technique, the right guard and right tackle doubling him, and the center blocking back next to them. The 3 holds it alone, and the Mike’s job has moved outside the pile, four gaps over. He did not freelance. He read his key, saw power, and went where the plan said power’s gap would appear, and the Will, who shuffles behind the double team, inherits the gap the Mike left if the ball cuts back into it. Every linebacker’s read in Linebackers and the Second Level is a question about where his gap has gone.

Fits against zone: when the gaps keep moving

Power tells the defense where it is going. A pulling guard is a signpost, and a defense that reads it can fit the gap the play creates. Zone does the opposite. As Zone Running showed, the whole line steps the same way and the running back picks the hole after the snap, so there is no single gap to fit. The gaps slide sideways with the blockers, and the back is reading the defenders to see which one is out of place.

Against zone, then, a fit is less a spot than a relationship: stay on the correct side of your blocker, and stay a gap behind the ball. Figure 32.4 draws it against outside zone.

Show the Python
off = line() + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("RB", "RB", -7.0, 0, "R")]
dfn = even4(sam_w=6.6) + [D("SS", "SS", 11.0, 8.0, "SS"), D("FS", "FS", 11.0, -8.0, "FS")]
p = Play(off, dfn, los=35, to_go=None, title="Fitting outside zone: the gaps move, so the fits move")
ZONE_STEP = 2.6                                     # how far the whole line slides in the first second
for k in ("LT", "LG", "C", "RG", "RT", "Y"):
    p.block(k, pts=[(0.9, ZONE_STEP + (0.3 if k in ("RT", "Y") else 0.0))])
go_to(p, "RB", (-1.5, 7.2), "run", via=[(-6.0, 2.6), (-3.6, 5.6)])
go_to(p, "SE", (0.9, 7.0), "path", speed=3.0)        # play-side end: step with the reach, outside arm free
go_to(p, "DT", (0.9, 4.6), "path", speed=3.0)
go_to(p, "NT", (0.9, 2.1), "path", speed=3.0)
go_to(p, "SAM", (3.0, 10.5), "path", speed=4.5)      # force: outside-in
go_to(p, "MIKE", (3.0, 4.6), "path", speed=4.5)      # fast flow, stay behind the ball
go_to(p, "WILL", (3.4, 0.2), "path", speed=2.5)      # slow flow: the cutback
go_to(p, "WE", (0.6, -1.2), "path", speed=3.5)       # backside end: squeeze flat down the line and chase
go_to(p, "SS", (6.6, 9.2), "path", speed=4.0)        # play-side safety: the alley
go_to(p, "FS", (7.4, -1.0), "path", speed=4.0)       # backside safety: cutback lane
p.highlight("WILL", color=WATCH_RING); p.highlight("SAM", color=FORCE_RING)
f = draw(p, width_in=5.9, lateral=(-12.0, 15.5), window=(-9.0, 13.5))
for w, g in [(-0.8, "A"), (0.8, "A"), (-2.4, "B"), (2.4, "B"), (-4.0, "C"), (4.0, "C"), (5.6, "D")]:
    gap_tag(f, p, -3.4, w, g, fontsize=6.0)
    gap_tag(f, p, -4.7, w + ZONE_STEP, g, color=style.MUTED, fontsize=5.6)
say(f, p, -3.4, -7.4, "gaps at the snap", color=GREEN, fontsize=6.2, weight="bold")
say(f, p, -4.7, -7.4, "...one second later", color=style.MUTED, fontsize=6.2)
point_to(f, p, (-3.2, 11.6), (1.0, 4.0), "end: stretch with the\nreach, outside arm free", color=style.DEFENSE_DARK)
point_to(f, p, (6.3, 13.4), (3.0, 10.5), "S: force,\noutside-in", color=PURPLE, weight="bold")
point_to(f, p, (9.6, 12.4), (6.6, 9.2), "SS: alley", color=GREEN, weight="bold")
point_to(f, p, (7.6, 2.6), (3.6, 3.4), "M: fast flow, a gap\nbehind the ball", color=style.DEFENSE_DARK)
point_to(f, p, (2.4, -8.2), (4.4, -2.0), "W: slow flow,\nown the cutback", color=style.DEFENSE_DARK, weight="bold")
point_to(f, p, (8.4, -8.6), (9.4, -4.9), "FS: cutback\nlane", color=style.DEFENSE_DARK)
point_to(f, p, (-1.6, -9.0), (1.0, -4.0), "end: squeeze,\nchase, boot", color=style.DEFENSE_DARK)
plt.show()
Figure 32.4: Fitting outside zone right. The whole line steps right together and the back aims wide, so the gaps slide with the blockers: the green letters are the gaps before the snap, the faded ones where the same gaps are a second later. The play-side end (5) stretches with the tackle’s reach and keeps his outside arm free; the Sam is the force (purple ring), coming up outside-in, with the strong safety behind him filling the alley; the Mike flows fast but stays a gap behind the ball; the Will slow-flows and owns the cutback (orange ring), with the free safety coming down behind him into the cutback lane; the backside end squeezes, chases and watches for the bootleg.
  • The play-side edge doesn’t spill. On outside zone there is no kick-out to spill. The tackle or tight end is trying to reach the end man, get his head outside and seal him in. So the end stretches with the reach, keeps his outside arm free and makes the ball cut up inside him. The Sam outside him is the force, coming up outside-in to stop the back from winning the corner, with the strong safety filling the alley inside him. Together they squeeze the run back toward the middle, where the outside zone runner does not want to be. (Zone has one variation that brings the kick-out back: in split zone a tight end or H-back crosses behind the line and blocks the backside end much like a kick-out, and that end chooses spill or box all over again.)
  • The play-side linebacker runs, but behind the ball. Fast flow, but never ahead of the running back’s helmet. A linebacker who over-runs the play (gets outside the ball) has given the back a lane behind him, and zone is designed to find exactly that lane.
  • The backside owns the cutback. This is where zone hurts defenses. Outside zone’s biggest runs are cutbacks, so the backside linebacker slow-flows (shuffles, waiting) and owns the cutback lane, and the backside safety comes down behind him, the last defender in it. The backside end squeezes down the line, chasing from behind, but with one eye on the quarterback: outside zone’s best friend is the bootleg the other way.

Zone also explains the most common failure of gap integrity on a broadcast. When a zone run gets eight yards on a cutback, rewind and look at the backside linebacker. Usually he flowed with everyone else, two defenders ended up in the same play-side gap, and the backside gap he owned was empty. The back didn’t make the hole. The defense gave it to him.

The plus-one: where the extra defender comes from

So far this chapter has assumed something it hasn’t said out loud: the defense has enough players to own every gap and still have someone left over. Where does that someone come from?

The Language of the Run Game introduced hat math: count the offense’s blockers, count the box, and compare. A First Look at Defense turned it into a scale (light, normal, loaded). The defensive side of that arithmetic has a name. The plus-one is having one more run defender than the offense has blockers, so one defender is unblocked and free to make the tackle. With six blockers, it means seven run defenders; with seven, eight.

Why one more? Because if the numbers are even, every defender can be blocked. A hat on every hat means the runner reaches the second level untouched unless some defender beats his blocker, and the defense would be betting its whole run defense on winning one-on-one fights. With a plus-one, the defense doesn’t need to win a single block. It needs every defender to hold his gap, and the extra man makes the tackle. Look at the fit chart again: the strong safety is the plus-one, and his job, force, is the one nobody on the offense was assigned to block.

The plus-one almost always comes from the secondary, because that is where the spare players are. The defense starts with eleven; the corners are usually busy with the wide receivers, and one deep safety stays back to prevent the long pass. Everyone else can be a run defender. So the cleanest way to add a defender to the box is to bring a safety down, and the cleverest way is to bring him down at the snap, after the quarterback has looked at the defense.

Show the Python
off = single_back_11()
dfn = even4() + [D("NB", "NB", 4.5, -6.5, "$"), D("LCB", "CB", 7.0, -15.0, "CB"), D("RCB", "CB", 7.0, 15.0, "CB"),
                 D("SS", "SS", 12.5, 8.5, "SS"), D("FS", "FS", 12.5, -8.5, "FS")]
p = Play(off, dfn, los=35, to_go=None, title="The plus-one: a safety rotates into the box at the snap")
go_to(p, "SS", (5.5, 6.0), "path", speed=5.0)
go_to(p, "FS", (13.5, 0.0), "path", speed=5.0)
f = draw(p, width_in=6.2, lateral=(-18.0, 18.0), window=(-8.0, 16.0))
lane(f, p, -5.4, 7.6, -0.6, 7.0, color=style.DEFENSE, alpha=0.05)
x, y = _P(f, p, 5.5, 6.0)
f.ax.add_patch(RegularPolygon((float(x), float(y)), 4, radius=0.94, orientation=np.pi / 4, fc=style.DEFENSE_TINT,
                              ec=style.DEFENSE, lw=1.3, zorder=8))
f.ax.text(float(x), float(y), "SS", fontsize=6, fontweight="bold", color=style.INK, ha="center", va="center", zorder=10)
f.ax.add_patch(Circle((float(x), float(y)), 1.45, fc="none", ec=FORCE_RING, lw=2.0, zorder=7))
say(f, p, -4.2, 11.0, "blockers: 6\n(5 linemen + Y)", fontsize=6.8)
say(f, p, 9.6, -12.0, "before the snap:\n6 in the box v 6 blockers", fontsize=6.8)
say(f, p, 3.0, 11.8, "after the rotation:\n7 v 6, the plus-one", color=PURPLE, fontsize=6.8, weight="bold")
point_to(f, p, (10.4, -3.6), (13.3, -2.0), "FS rotates to the\ndeep middle", color=style.DEFENSE_DARK)
plt.show()
Figure 32.5: The plus-one. Before the snap the defense shows two high safeties and six defenders in the box (shaded) against six blockers: a light box. At the snap the strong safety rotates down (arrow) to the spot ringed in purple, just outside the tight end and inside the shaded box, and the free safety rotates to the deep middle. The box is now seven against six, with one defender nobody is assigned to block. The nickel back ($) stands outside the box, over the slot receiver.

In Figure 32.5 the defense shows two high safeties before the snap. Count the box: four linemen and two linebackers, six defenders against six blockers (five linemen and the tight end). That is a light box, and a quarterback with the freedom to check to a run at the line would be tempted. At the snap, the strong safety rotates down into the box and the free safety slides to the deep middle. Now it is seven against six, the plus-one, and the shell has turned from two-high into one-high. (The nickel back outside the box on the left is the overhang defender of A First Look at Defense, standing between the box and the slot receiver. He is not counted in the box, but he is not out of the run game either; the drills below come back to him.) How the defense hides that move until the last moment, and the names for the many ways to do it (a sky rotation, a spin on motion), are the subjects of Cover 3 and Disguise and Rotation.

The offense’s answers, and the defense’s answers to those

The plus-one is not a fixed fact. It is the opening position in a negotiation, and each side has a short list of moves.

The offense can add a blocker. A second tight end or a fullback makes seven blockers, so the defense needs eight to stay plus-one. That is why heavy personnel is a run-game tool, and why it came back: in 2025 NFL offenses used fewer than three wide receivers on 41.7% of plays, the first season at or above 38% since Next Gen Stats began tracking in 2016.5

The offense can spread the defense out. Every receiver split wide pulls a defender with him. Four wide receivers leave the defense with fewer players to put in the box at all.

The offense can read the free man instead of blocking him. This is the option idea from Option Football, and it is the plus-one’s natural enemy. If the quarterback reads the unblocked defender and keeps the ball whenever that defender chases the back, the offense has “blocked” him without spending a blocker, and the count is even again. So the rule of box math with a running quarterback is simple: count the quarterback as a blocker. Six blockers plus a quarterback who reads is seven. Designed quarterback runs get there from the other direction. On QB power or QB counter the quarterback carries the ball and the running back, no longer the runner, becomes one more lead blocker: the same plus-one for the offense.

The offense can throw. Every safety in the box is a safety not covering a deep zone. The run-pass option (RPOs) and play-action both turn the plus-one into a target.

And the defense’s answers? It can bring yet another safety, and play with no deep safety at all, a gamble you will meet in Blitz and Man Pressure. It can change the technique instead of the numbers: put five men on the line, with a nose who two-gaps the center, so that the offensive line can’t reach the linebackers and they stay free to fit. That is the tite front of Odd and Hybrid Fronts. Or it can accept the light box and fit the run from depth, which is the next section, and the biggest strategic argument in the NFL right now.

Fitting the option: the gap exchange

The zone read is plus-one arithmetic with a quarterback in it. Option Football showed the offense’s view: block everyone but the backside end, read him, and hand the ball to whichever runner he is not taking. The defense’s fit chart has to say who takes the running back and who takes the quarterback, and the simplest version says the end takes the quarterback (he stays home) and the linebacker behind him takes the inside gap. The offense knows that chart, so the end’s behaviour tells the quarterback what to do.

The defense’s answer is to change the chart after the snap. A gap exchange is a planned swap of gap responsibilities between two defenders after the snap: one takes the other’s gap and vice versa. The best-known version is the scrape exchange from 03-04: the end crashes inside at the running back, which is the “keep” read, and the linebacker behind him scrapes around the end’s outside to take the quarterback. You have seen it twice already, from the quarterback’s side in Option Football and from the Will’s in Linebackers. What is new here is the ownership. Figure 32.6 runs the same play as a fit, and the tags show what each defender owns, before the snap and after it.

Show the Python
off = line(puller="LG") + [te(+1), O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, -1.6, "R")]
dfn = even4() + [D("SAM", "SAM", 4.4, 6.4, "S")]
ZR = Play(off, dfn, los=35, to_go=None)
for k, end in [("LT", (0.4, -2.6)), ("C", (0.4, 0.5)), ("RG", (0.4, 2.6)), ("RT", (0.5, 4.2)), ("Y", (0.6, 6.0))]:
    go_to(ZR, k, end)
go_to(ZR, "LG", (3.4, -2.0), via=[(-0.3, -1.4), (1.0, -1.8)])     # climbs to where the Will was
go_to(ZR, "WE", (-2.4, -2.0), "path", speed=4.0)                  # the end crashes on the back
go_to(ZR, "WILL", (-0.6, -6.6), "path", speed=5.6, via=[(3.6, -4.8), (1.4, -6.4)])   # scrapes around the end
go_to(ZR, "RB", (1.2, 2.4), "path", via=[(-4.7, -0.4), (-3.4, 1.0)])          # the fake
go_to(ZR, "QB", (0.6, -7.6), "run", delay=0.6, via=[(-4.6, -1.0), (-2.6, -4.6)])
go_to(ZR, "MIKE", (3.4, 2.6), "path", speed=3.0)
go_to(ZR, "SAM", (3.0, 6.8), "path", speed=2.5)


def exchange_tags(fld, play, t, i):
    """Ownership tags, each sitting next to the defender it describes."""
    e, w = play.position("WE", t), play.position("WILL", t)
    if t < 0.3:
        point_to(fld, play, (e[0] + 1.9, e[1] - 2.6), tuple(e), "E: the QB", color=style.DEFENSE_DARK, fontsize=6.2)
        point_to(fld, play, (w[0] + 2.0, w[1] + 2.0), tuple(w), "W: inside", color=style.DEFENSE_DARK, fontsize=6.2)
    else:
        point_to(fld, play, (e[0] - 1.9, max(e[1] - 3.2, -9.3)), tuple(e), "E: the back", color=GREEN, fontsize=6.2,
                 weight="bold")
        late = t >= 1.7
        point_to(fld, play, (w[0] + (3.0 if late else 2.2), max(w[1] + (2.4 if late else 0.6), -8.8)), tuple(w),
                 "W: the QB", color=GREEN, fontsize=6.2, weight="bold")
    if t >= 1.7:
        spot(fld, play, 1.7, -7.5)


animation_or_strip(
    [(ZR, 0.0, ""), (ZR, 0.6, ""), (ZR, 1.1, ""), (ZR, 1.8, "")],
    ["the plan the Q expects:\nthe end has the QB",
     "the end crashes: the read\nsays 'keep'",
     "the Q pulls it; the Will is\nalready scraping outside",
     "the Will meets the Q;\nthe G climbed to nobody"],
    lateral=(-11.5, 8.5), window=(-7.5, 8.5), ncols=2, width_in=5.6,
    rings=(("WILL", WATCH_RING), ("QB", BALL_RING)), after=exchange_tags)
Figure 32.6: The scrape exchange as a run fit (simulated). The line zones right and the quarterback reads the backside end. The tags show who owns what: before the snap the end has the quarterback and the Will (orange ring) the inside gap; at the snap they swap. The end crashes on the back, the quarterback (gray ring) sees ‘keep’ and pulls the ball, and the Will, scraping around the end, meets him. The left guard (G) climbs to where the Will used to be and finds nobody: the offense’s blocking was built on the first picture.

The quarterback did everything right. He read the end, the end took the back, and he kept the ball. The defense simply moved the man who owned the quarterback, and it did it after the quarterback’s eyes had stopped looking for him. Notice the gap the Will left behind: it is not empty, because the crashing end is now standing in it. That is the whole trick of an exchange: every gap still has exactly one owner, only the names have changed.

The exchange still has costs, and offenses aim at them:

  • Arc. A tight end or H-back runs around the read end to block the scraping linebacker (the arc block of 03-02). Now the scraper is blocked, the end is inside, and nobody has the quarterback.
  • Bend. An end who crashes too flat and too deep goes past the back, who bends behind him into the gap the Will just left. The crash has to arrive under control, on the back’s near hip.
  • Read the scraper. The offense can block the end and read the linebacker instead, or flip the roles with the inverted veer or bash of 03-04, so that the exchange points the wrong way.
  • Depth. The scraper has to get from about four and a half yards deep to the quarterback’s path before the quarterback gets there. A linebacker lined up deeper or wider than usual, to give himself time, is a tell the quarterback can see before the snap.

A gap exchange is a bet that the offense will read the first picture.

Gap exchanges are not only for the option. A defensive line slant (05-01) is a gap exchange for a whole front: every lineman moves over one gap and the linebackers move the other way to fill what they left. An end who “spikes” (slants hard to the gap inside him at the snap) while the outside linebacker takes his C gap is one; so is a linebacker who blitzes through the A gap while the nose loops into the B gap. The idea is always the same: keep gap integrity (every gap still has exactly one owner) while changing which defender owns it, so the blocking scheme and the quarterback’s read, both built on the pre-snap picture, are wrong. That is also the logic of the simulated pressures of Part 7, applied to the pass game.

Against a team built on the option, defenses also rewrite the chart in option language. Instead of gaps, a coach assigns dive (the running back on the inside run), quarterback and, if there is one, pitch, and he makes sure each has an owner on every play, with the assignments rotating between players from snap to snap so the quarterback never sees the same picture twice. That is the logic you will see from the defensive side of The Ravens’ Option Run Game.

Two-high and the light box: inviting the run on purpose

Everything so far says the defense wants a plus-one in the box. For most of football history, that was the end of the discussion. Then, starting in the late 2010s, more and more NFL defenses began doing something that looked backward: keeping both safeties deep, playing six (sometimes five) defenders in the box against six blockers, and daring the offense to run.

Here is the shape of it.

Show the Python
off = single_back_11()
dfn = [D("WE", "DL", 1.0, T("5", -1), "5"), D("NT", "DL", 1.0, T("1", -1), "1"),
       D("DT", "DL", 1.0, T("3", 1), "3"), D("SE", "DL", 1.0, T("5", 1), "5"),
       D("MIKE", "MIKE", 4.8, 1.0, "M"), D("WILL", "WILL", 4.8, -2.4, "W"), D("NB", "NB", 4.5, -7.0, "$"),
       D("LCB", "CB", 7.0, -15.0, "CB"), D("RCB", "CB", 7.0, 15.0, "CB"),
       D("SS", "SS", 12.5, 8.5, "SS"), D("FS", "FS", 12.5, -8.5, "FS")]
p = Play(off, dfn, los=35, to_go=None, title="Two-high, light box: the plus-one comes from 12 yards away")
for k, end in [("LT", (0.4, -4.0)), ("LG", (3.6, -2.3)), ("C", (0.4, -0.6)), ("RG", (3.6, 1.0)),
               ("RT", (0.4, 2.4)), ("Y", (0.4, 4.6))]:
    go_to(p, k, end)
go_to(p, "RB", (4.3, 3.4), "run", via=[(-5.2, 0.6), (-1.0, 2.4)])
go_to(p, "SS", (5.3, 4.6), "path", speed=6.0)
go_to(p, "FS", (5.5, 2.4), "path", speed=6.0)
p.highlight("SS", color=FORCE_RING); p.highlight("FS", color=FORCE_RING); p.highlight("RB", color=BALL_RING)
f = draw(p, width_in=6.0, lateral=(-17.0, 17.0), window=(-8.0, 15.5))
lane(f, p, -5.4, 6.4, -0.6, 6.5, color=style.DEFENSE, alpha=0.04)
lane(f, p, 2.3, 5.4, 3.5, 5.5, color=style.OFFENSE, alpha=0.10)
say(f, p, 9.6, -12.4, "the box: 6 defenders\nv 6 blockers, a hat\non every hat", fontsize=6.6)
point_to(f, p, (1.6, -12.0), (4.5, -7.0), "$: outside the box,\nheld there by the H", color=style.DEFENSE_DARK,
         fontsize=6.4)
point_to(f, p, (-3.2, 10.4), (4.4, 5.2), "the run gets here\nbefore a safety arrives:\n4 to 5 yards",
         color=style.OFFENSE_DARK, fontsize=6.6)
point_to(f, p, (10.0, 1.6), (8.9, 6.5), "safeties fill from depth:\nthe plus-one, late", color=PURPLE, fontsize=6.6)
plt.show()
Figure 32.7: The two-high light box against inside zone. Six blockers (five linemen and the Y) against six defenders in the shaded box: the guards climb to the linebackers and every box defender has a blocker. The nickel back ($) stands outside the box over the slot receiver (H), who keeps him there. The defense’s free men are the two safeties (purple rings), filling from 12 yards. By the time they arrive, the run has reached the shaded lane, four or five yards past the line: the yards the defense has agreed to give. On this two-high picture the force on the nickel’s side is the $, and on the tight end’s side, with nobody outside the end, the safety comes down outside-in.

In Figure 32.7 the box is even: six defenders, six blockers, a hat on every hat. Nobody in the box is free. The plus-one still exists, but it is twelve yards away: the two safeties, who read run and come downhill as alley players. They are the defense’s free men, and they arrive late, somewhere around four or five yards downfield.

Why four or five? Rough arithmetic, not a measurement, makes the number believable. Give the safety half a second to read his key and be sure it is a run. Then he runs downhill, speeding up, at an average of about six yards a second: by two seconds after the snap he has covered about nine yards on a diagonal toward the ball, which brings him from twelve yards deep to about five. The running back takes the handoff about seven yards behind the line and crosses it about 1.2 seconds after the snap, running about six yards a second, so by two seconds he is about five yards past the line. Their paths cross four or five yards downfield. A safety who reads it a tenth of a second faster, or starts at ten yards instead of twelve, saves a yard; one who hesitates gives one away. That is the price the defense has agreed to pay on every run, in exchange for something it values more.

Who is the force in a light box? Apply the rule from the force section to each side. On the nickel’s side the force is the $, the overhang defender, who is outside the box precisely so he can be both the edge against the run and a cover man on the slot. On the tight end’s side there is no one outside the end before the snap, so either the end sets the edge himself or, as in the figure, a safety comes down outside-in and the end plays inside him. Either way, the force on that side is arriving late, which is one more reason runs aimed at the tight end’s edge do well against two-high.

Why a defense would do this

Explosive passes cost more than runs. In EPA terms (the primer is in Downs, Distance and Field Position), the average pass is worth more than the average run, and the plays that lose games for a defense are explosive passes. Two deep safeties are the best protection against them. A defense that keeps two high is choosing to give up four-yard runs rather than forty-yard passes.

Two-high shells can disguise. A defense that shows two safeties can still rotate into one-high at the snap (the plus-one of Figure 32.5) or play any of the two-high coverages behind it. The light box keeps the offense guessing about who will be in it a second after the snap.

It has been spreading. Next Gen Stats measured split-safety (two-high) coverage on 32.9% of plays in 2018, 40.4% in 2024 and 42.0% in 2025, the highest since its tracking began.6 The box counts moved with it: in the nflverse data, designed runs met six or fewer defenders in the box about 38% of the time in 2018–2022, and 58% and 55% of the time in 2024 and 2025.7

The coach most associated with the approach is Vic Fangio, an NFL assistant for more than thirty years before Denver made him a first-time head coach at 60 (2019–2021). His two-high defenses in Chicago and Denver spread across the league, carried first by coaches who had worked for him, such as Brandon Staley.8 His approach is simple to state: keep two safeties deep to take away the explosive pass, and ask the front to hold the run without help. His linemen are asked to win their own fights and, at times, to “steal” back gaps the box does not have bodies for, as a Philadelphia beat writer put it in 2024.9 How the shift to two-high started (this book calls it the two-high counterrevolution), and the answer to it, are history for The Modern Era and a case study, Fangio’s Two-High Revolution and Macdonald’s Answer.

What it costs

The light box is a trade, and the bill comes in four parts.

  • Yards. Runs against six-man boxes average more than runs against seven or eight: on early downs in the data below, about a quarter of a yard more per carry than against seven and more than half a yard more than against eight or more. A defense that lives in light boxes will look bad in rushing yards allowed, and it has accepted that.
  • The front must be good enough to hold. A six-man box has no margin. If one lineman is moved off his gap, there is no spare linebacker behind him; the next defender is a safety at twelve yards. Light-box defenses need linemen who can take on double teams and two-gap when they have to, which is why they pay for big interior players and why the tite front of Odd and Hybrid Fronts became their favourite shape.
  • The safeties must tackle. A safety fitting from depth meets the runner at full speed, in space, often one-on-one. A missed tackle there is not a four-yard run. It is a forty-yard run, because there is nobody behind him.
  • Heavy personnel attacks it. Against a light box, the offense’s simplest move is to add blockers, and the rise of two- and three-tight-end sets in 2024 and 2025 is partly that. Each extra blocker forces the defense to choose again: match it with a heavier package (base defense was on the field for 29.7% of snaps in 2025, up from a low of 20.5% in 2023) or accept being outnumbered in the box.10
CautionCommon misconception

“A light box means the defense is soft against the run.” The best run defense of 2024 by EPA was one of the lightest boxes in the league: Fangio’s Eagles (see the film room below). A light box is not the absence of a run fit. It is a fit that uses the safeties instead of an eighth man at the line, and that asks more of the defensive line.

What the data says: box count and EPA

You can test all of this with the nflverse data. The participation files record how many defenders were in the box at the snap on almost every play, and the play-by-play records the result. Figure 32.8 compares designed runs and dropbacks by box count, on first and second down in neutral situations (so that third-and-long and the goal line, where box counts and outcomes are both extreme, don’t tilt the picture), for two eras of the data that count the box in slightly different ways.

Show the Python
from gridiron.data import nfl, pbp

style.apply()
frames = []
for yr in range(2018, 2026):
    part = nfl().load_participation([yr]).to_pandas()[["nflverse_game_id", "play_id", "defenders_in_box"]]
    pb = pbp(yr, columns=["game_id", "play_id", "season_type", "play_type", "down", "rush", "pass", "qb_scramble",
                          "epa", "success", "yards_gained", "wp", "half_seconds_remaining", "yardline_100",
                          "posteam", "defteam"])
    pb = pb[(pb.season_type == "REG") & pb.play_type.isin(["pass", "run"]) & pb.down.notna() & pb.epa.notna()]
    m = pb.merge(part, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
    m["season"] = yr
    frames.append(m)
PLAYS = pd.concat(frames, ignore_index=True)
PLAYS = PLAYS[PLAYS.defenders_in_box >= 3]               # a few rows record 0-2: "not recorded"
PLAYS["designed_run"] = (PLAYS.rush == 1) & (PLAYS.qb_scramble != 1)
PLAYS["dropback"] = PLAYS["pass"] == 1

neutral = PLAYS[PLAYS.down.isin([1, 2]) & PLAYS.wp.between(0.2, 0.8) & (PLAYS.half_seconds_remaining > 120)
                & (PLAYS.yardline_100 > 10)].copy()
neutral["box"] = neutral.defenders_in_box.clip(5, 8).astype(int)
neutral["era"] = np.where(neutral.season <= 2022, "2018–2022 (NGS)", "2023–2025 (FTN)")


def mean_ci(d):
    return pd.Series({"epa": d.epa.mean(), "ci": 1.96 * d.epa.std() / np.sqrt(len(d)), "n": len(d)})


fig, axes = plt.subplots(1, 2, figsize=(6.5, 3.2), sharey=True)
labels = {5: "5 or\nfewer", 6: "6", 7: "7", 8: "8 or\nmore"}
for ax, (flag, ttl) in zip(axes, [("designed_run", "Designed runs"), ("dropback", "Dropbacks")]):
    for i, (era, g) in enumerate(neutral[neutral[flag]].groupby("era")):
        s = g.groupby("box").apply(mean_ci)
        xs = np.arange(len(s)) + (i - 0.5) * 0.16
        ax.errorbar(xs, s.epa, yerr=s.ci, marker="o", ms=4.5, lw=1.8, capsize=2.5, color=style.SERIES[i],
                    label=era)
    ax.axhline(0, color=style.BASELINE, lw=0.9)
    ax.set_xticks(range(4), [labels[k] for k in range(5, 9)], fontsize=8)
    ax.set_xlabel("defenders in the box at the snap", fontsize=8)
    ax.set_title(ttl, fontsize=9)
    ax.grid(axis="x", visible=False)
axes[0].set_ylabel("EPA per play", fontsize=8)
axes[1].legend(fontsize=7.5, loc="upper left")
fig.tight_layout()
plt.show()
Figure 32.8: EPA per play by the number of defenders in the box at the snap, regular seasons 2018–2025, first and second down, the game still in doubt (win probability 20–80%), outside the last two minutes of each half and outside the opponent’s 10-yard line. Left: designed runs (quarterback scrambles excluded). Right: dropbacks (passes, sacks and scrambles). Each extra defender in the box costs runs about 0.02 to 0.05 expected points and is worth about the same to the passing game, the box as a budget. Even against the lightest boxes, runs average less than dropbacks do against the heaviest. The two lines are the two data sources (NGS for 2018–2022, FTN for 2023–2025), which count the box slightly differently; bars are 95% intervals. Data: nflverse play-by-play and participation via nflreadpy.

Read the left panel first. The more defenders in the box, the worse runs do: on these downs, designed runs averaged about −0.03 EPA against five or fewer in the box, −0.05 against six, −0.09 against seven and −0.15 against eight or more, and their success rates fell from about 41% to 34% across the same range.11 Both data sources agree on the slope. The plus-one is real: each defender the defense adds to the box takes something away from the run.

Now the right panel, which is the part that explains the two-high era. The same extra defender helps the passing game. Dropbacks against five or fewer in the box averaged about +0.06 EPA; against seven, about +0.12; against eight or more, about +0.16 in the 2018–2022 data. The box is a budget: a defender spent near the line is a defender not spent in coverage, and the offense’s passing game cashes the difference. (The 2023–2025 point for eight or more dropbacks rests on only about 800 plays, which is why its interval is so wide.)

And look at the two panels side by side. Against every box count, the average dropback beats the average designed run. Even against the lightest boxes, runs averaged less than zero EPA; even against the heaviest, dropbacks averaged more than zero. The slopes are about the same size, too: an extra defender in the box takes roughly as much from the run as it gives to the pass. So, on averages alone, the light box is close to a wash. Why call it a reasonable bet, then? Three numbers from the same data tip it.

  • Where the big plays come from. Against six in the box, 8% of dropbacks gained 20 yards or more; against seven, 11%. The share of designed runs gaining 10 or more barely moved: 12% against six, 12% against seven.12 Taking a safety out of the deep field buys the offense explosive passes; putting him back buys the run game almost nothing big. A defense that fears the long ball more than the four-yard run, as Fangio’s does, is reading this line.
  • The run it gives up is still a losing play. At −0.05 EPA, a designed run against a six-man box still leaves the offense slightly worse off, on average, than before the snap. Conceding it costs less than it looks on a rushing-yards table.
  • Don’t expect the offense to be “steered.” You might think a light box lures offenses into running more. In these situations the raw numbers say the opposite: offenses ran on 43% of plays against six in the box and 55% against seven (same footnote). That is the defense’s choice showing through, not the offense’s: defenses lighten the box against spread formations that usually throw and load it against heavy ones that usually run. The bet is not that the offense will take the bait. It is that whatever the offense does, the defense has spent its players where the bigger danger is.

If dropbacks beat runs at every box count, why does anyone run? Because the averages only hold at the mix offenses actually use. Runs keep defenses from dropping everyone into coverage; an offense that stopped running would soon see those same dropbacks against eight defenders in coverage, and the gap would close. And this chart leaves out the situations where running is clearly right: short yardage, the goal line, protecting a lead late. The light box is a bet on the margin, not a claim that the run is dead.

Three cautions keep this honest.

  • The box count is measured at the snap. A safety who rotates down after the snap, like the one in Figure 32.5, is counted out of the box. Some “six-man boxes” in the data were seven-man fits a second later, which makes light boxes look a little better against the run than the fits really were.
  • Boxes are chosen, not assigned at random. Defenses load the box when they expect a run and empty it when they expect a pass, and offenses check into runs against light boxes. Holding the down and the game situation fixed, as this chart does, removes the worst of that, but not all of it. A First Look at Defense showed how flat these comparisons look when you don’t.
  • The data changes source between 2022 and 2023. Next Gen Stats (the NFL’s player-tracking data) supplied the box count through 2022, and FTN, a data company whose staff chart every play by hand, from 2023. They draw the box differently, so read the two lines as two measurements, not one trend.
NoteGo deeper

Finding the force in tracking data. The “Watch for it” rule (the outermost defender within about seven yards of the line on each side, ignoring a corner who is deep or pressed on his man, but counting a corner who squats at about five yards when both safeties are deep) is easy to turn into code. Here it is run on two simulated plays exported in Big Data Bowl format (these frames are simulated, BDB-format, not real tracking): the single-high fit chart of Figure 32.3 and the two-high picture of Drill 1, below.

Show the Python (find the probable force player on each side at the snap)
ROLE = {"WE": "backside end (5)", "SE": "play-side end (5)", "SAM": "Sam (S)", "SS": "strong safety",
        "FS": "free safety", "LCB": "left corner", "RCB": "right corner", "NB": "nickel ($)",
        "MIKE": "Mike", "WILL": "Will", "NT": "nose (1)", "DT": "tackle (3)"}


def force_candidates(trk, max_depth=7.0, corner_depth=(3.0, 6.0), deep=10.0):
    """Outermost defender on each side within `max_depth` yards of the line at the snap: the probable force.
    A corner counts only if he squats `corner_depth` yards off the ball AND at least two defenders are deeper
    than `deep` (the Cover 2 'cloud' corner); a deep or pressed corner is ignored. A pre-snap guess:
    rotation after the snap can change it."""
    snap = trk[trk["frameType"] == "SNAP"]
    ball = snap[snap["side"] == "ball"].iloc[0]
    los, mid = ball["x"], ball["y"]
    dfn_all = snap[snap["side"] == "def"].copy()
    dfn_all["depth"] = dfn_all["x"] - los
    two_deep = (dfn_all["depth"] > deep).sum() >= 2
    rows = []
    for side_name, sgn in (("offense's right", -1), ("offense's left", 1)):   # offense faces +x: right = -y
        dfn = dfn_all[(dfn_all["y"] - mid) * sgn > 0].copy()
        dfn["width"] = (dfn["y"] - mid) * sgn
        corner = dfn["position"] == "CB"
        squat = corner & dfn["depth"].between(*corner_depth) & two_deep
        dfn = dfn[(dfn["depth"] <= max_depth) & (~corner | squat)]
        top = dfn.sort_values("width").iloc[-1]
        rows.append({"side": side_name, "probable force": ROLE.get(top["displayName"], top["displayName"]),
                     "yards outside the ball": round(top["width"], 1), "depth": round(top["depth"], 1)})
    return pd.DataFrame(rows)


fit_play = Play(i_form(), sky_defense(), los=35, to_go=None)
cloud_play = Play(single_back_11(), even4() + [
    D("NB", "NB", 4.5, -6.5, "$"), D("LCB", "CB", 4.5, -15.8, "CB"), D("RCB", "CB", 4.5, 15.8, "CB"),
    D("SS", "SS", 12.0, 7.5, "SS"), D("FS", "FS", 12.0, -7.5, "FS")], los=35, to_go=None)
for name, play in [("Single-high fit chart (Cover 3, sky)", fit_play), ("Drill 1 (two-high, squatting corners)",
                                                                           cloud_play)]:
    print(name)
    print(force_candidates(play.to_tracking()).to_string(index=False), "\n")
Single-high fit chart (Cover 3, sky)
           side   probable force  yards outside the ball  depth
offense's right    strong safety                     9.5    6.5
 offense's left backside end (5)                     4.0    1.0 

Drill 1 (two-high, squatting corners)
           side probable force  yards outside the ball  depth
offense's right   right corner                    15.8    4.5
 offense's left    left corner                    15.8    4.5 

On the single-high fit chart it finds the strong safety on the right, the force in the table, and on the left, with no tight end and a deep corner, the backside end. On the two-high picture it finds both squatting corners, the Cover 2 force. With real Big Data Bowl files the same function works on a prepared play; the website’s “Show the Python” has the code, which is not run in the build.

Show the Python (the same rule on real Big Data Bowl tracking; not run in the build)
import pandas as pd
from gridiron import bdb

trk = bdb.load_tracking("data/bdb/tracking_week_1.csv")
plays = pd.read_csv("data/bdb/plays.csv")
one = bdb.prepare(trk, plays, game_id=2022091100, play_id=55)   # any run play
one["displayName"] = one["displayName"].astype(str)
print(force_candidates(one))

Film room

NoteFilm room: Seattle Seahawks 2012–2015 (the eighth man)

The plus-one’s most famous modern home was Pete Carroll’s Seattle defense, built on single-high Cover 3. Earl Thomas played the deep middle, alone, and Kam Chancellor, a strong safety built like a linebacker, played near the line as the eighth man in the box. Seattle led the NFL in scoring defense four years running, 2012 through 2015.13 Watch any of their games from those seasons for one thing: where Chancellor is at the snap. He is the force on runs to his side, the plus-one in the box count, and the reason offenses that wanted to run on Seattle needed an extra blocker. Then watch what happens to Thomas when the offense fakes the run: he is the only deep defender, which is the cost of the eighth man.

NoteFilm room: Philadelphia Eagles 2024 (the light box that held)

Vic Fangio’s first Eagles defense, in 2024, is the light-box argument at full strength, and it started badly. Through the first two weeks the Philadelphia Inquirer reported six or fewer defenders in the box on 73.5% of snaps, the third-highest rate in the league, and the run defense looked shaky after the Falcons ran through it in Week 2.14 Fangio kept the shape. Over the full season, by this book’s count, opponents’ designed runs met six or fewer in the box about two thirds of the time (a different measure from the Inquirer’s early snap count, and again the third-highest rate), and the Eagles allowed the fewest EPA per designed run in the league.15 Every defense Fangio has run since 2019 (he spent 2022 as a consultant) has been among the five that met runs with six or fewer in the box most often.16 The bet rested on the interior of the line: tackles Jalen Carter and Jordan Davis, whom Fangio called “a better run defender than he is a pass rusher,” and Milton Williams.17 What to watch: the two safeties at 12–14 yards at the snap, the six-man box, and how often an interior lineman ends up with two blockers on him and doesn’t move. The defense is betting on the front, and in 2024 the bet paid off on the way to a Super Bowl LIX win over Kansas City, 40–22.

NoteFilm room: Baltimore Ravens 2019 (the box that wasn’t loaded enough)

The 2019 Ravens rushed for 3,296 yards, breaking an NFL team record that had stood since 1978, and Lamar Jackson ran for 1,206 of them on his way to a unanimous MVP.18 Box math explains why defenses could not simply load up. On a designed run with Jackson reading a defender, every box needed one more defender than it appeared to, because the quarterback counts as a blocker, and on a designed quarterback run (Jackson had 120 of them), the running back could turn into one more lead blocker. Defenses met the Ravens’ designed runs with seven or more in the box about 65% of the time, slightly more than they did the rest of the league, and still lost: the Ravens averaged about +0.10 EPA per designed run against seven-man boxes and about +0.04 against eight or more, where the league averaged −0.10 and −0.13. Jackson’s own designed runs averaged about 7.1 yards.19 What looks like a normal seven-man box on the broadcast was, against Baltimore, a light one. Watch any 2019 Ravens game for the defender the quarterback is reading, and count him out of the box.

NoteFilm room: Philadelphia Eagles 2024 offense (running at two-high)

The same season, on the other side of the ball, the Eagles showed what a good run game does to a light box, with a quarterback, Jalen Hurts, whom defenses also had to account for as a runner. Saquon Barkley ran for 2,005 yards, the ninth 2,000-yard season in NFL history.20 Against Philadelphia, defenses played six or fewer in the box on about 61% of designed runs (the league rate was about 59%), and the Eagles averaged about 5.4 yards per designed run against those boxes, against the league’s 4.7. About one in seven of those runs gained ten yards or more.21 That is the light box’s bill, paid in full: when the front cannot hold six blockers and the safeties arrive at five yards instead of three, the runs that get past them go a long way. What to watch: the safeties’ depth at the snap, the double teams on the interior, and the moment Barkley reaches the second level one-on-one with a safety coming downhill.

Watch for it on Sunday

TipWatch for it

Before the snap

  • Count the box, then count the blockers. Five linemen, plus every tight end and fullback near the line. If the quarterback is a runner who reads a defender, add him. More defenders than blockers: the defense has its plus-one in the box. Even: the plus-one is a safety, and he will arrive late.
  • Find the force on each side. Look for the outermost defender within about seven yards of the line. Ignore a corner who is deep or pressed on his receiver, but count a corner squatting at about five yards when both safeties are deep. A safety walked down outside the tight end: safety force (likely Cover 3, sky). Corners squatting at five yards with both safeties deep: corner force (likely Cover 2, cloud). A nickel or linebacker over the slot: he is the force on that side. Nobody out there but the end: the end is the force. With two tight ends or an unbalanced line, do it side by side: each side has its own end man and its own force.
  • Check the safeties’ depth. At 12–14 yards, they are alley players from depth and the box is what you see. At 8–10 yards and creeping, one of them is probably coming down at the snap.

After the snap

  • Did a safety rotate down? That is the plus-one arriving.
  • Watch the end man meet the kick-out or the puller. Dives under it: spill, so look outside for the force. Stays square, outside arm free: box, so look inside for the linebacker filling.
  • Did the run bounce? If it did, who met it outside, the force or nobody? If nobody, rewind and find the empty gap.
  • On a cutback, find the backside linebacker. If he flowed with everyone else, that is the gap the runner used.

Predict the play

TipPredict the play

Drill 1. Who’s the force? First-and-10, 11 personnel. The offense is about to run outside, to its right, toward the tight end and the Z receiver. Before the snap the defense shows the picture below. Who is the force on the play side, who is the alley player, and where do you expect the run to end up?

Show the Python
off = single_back_11()
dfn = even4() + [D("NB", "NB", 4.5, -6.5, "$"), D("LCB", "CB", 4.5, -15.8, "CB"), D("RCB", "CB", 4.5, 15.8, "CB"),
                 D("SS", "SS", 12.0, 7.5, "SS"), D("FS", "FS", 12.0, -7.5, "FS")]
p = Play(off, dfn, los=35, to_go=10, title="Drill 1: who forces a run to the right?")
f = draw(p, width_in=6.0, lateral=(-18.0, 18.0), window=(-8.5, 15.0))
dashed(f, p, [(-7.0, 0.0), (-5.6, 4.0), (-2.6, 8.5), (0.4, 11.0)], color=style.OFFENSE, lw=1.4)
say(f, p, -4.6, 11.8, "the run is\nheaded here", color=style.OFFENSE_DARK, fontsize=6.8)
plt.show()
Figure 32.9: Drill 1: before the snap. Both safeties are deep, 12 yards off the ball and about 7 or 8 yards either side of it, a little outside the hash marks (not drawn); both corners are squatting at about 5 yards, a step outside their receivers, facing the quarterback; six defenders in the box against six blockers.

The right cornerback is the force; the strong safety is the alley player. Two deep safeties and two corners squatting at five yards, outside their receivers, with their eyes on the quarterback is the classic Cover 2 shape. The corners have no deep zone to protect, so the play-side corner is free to come up outside-in, keep the ball inside him and turn it back. The strong safety, starting at twelve yards, reads run and comes down into the alley between the corner and the box.

Expect the run to be turned back inside around the numbers, and expect the defense to give up some yards doing it: six in the box against six blockers is a light box, and the alley player is arriving from twelve yards. The offense’s best counter is a receiver blocking the corner (the Z cracking down, or simply blocking him out), which is why, against Cover 2, the wide receivers’ blocks matter so much in the run game. One caution: corners squatting at five yards can also be a disguise, bailing to deep thirds at the snap (Disguise and Rotation). If that happens, the force becomes whoever rotates down, usually a safety.

TipPredict the play

Drill 2. Do the box math. Second-and-6. The offense is in shotgun with 11 personnel, and its quarterback is one of the league’s most dangerous runners. The defense shows two high safeties and six defenders in the box. How many blockers does the offense really have, who is the defense’s free man, and what run do you expect?

Show the Python
off = single_back_11(gun=True)
dfn = even4() + [D("NB", "NB", 4.5, -6.5, "$"), D("LCB", "CB", 7.0, -15.0, "CB"), D("RCB", "CB", 7.0, 15.0, "CB"),
                 D("SS", "SS", 12.5, 8.5, "SS"), D("FS", "FS", 12.5, -8.5, "FS")]
p = Play(off, dfn, los=35, to_go=6, title="Drill 2: count the box, then count the blockers")
f = draw(p, width_in=6.0, lateral=(-18.0, 18.0), window=(-8.0, 15.0))
lane(f, p, -5.4, 7.6, -0.6, 7.0, color=style.DEFENSE, alpha=0.05)
say(f, p, 9.2, 0.0, "the box", color=style.DEFENSE_DARK, fontsize=7)
plt.show()
Figure 32.10: Drill 2: before the snap. Shotgun, one back beside the quarterback, a tight end on the right; four defensive linemen and two linebackers in the box, a nickel back outside it on the left, two safeties at 12 to 13 yards.

Seven blockers against six, and the deep free men are twelve yards away. Five linemen and the tight end make six blockers, and the box holds six defenders: even. But a quarterback who runs and reads counts as a blocker, because the defender he reads is “blocked” by the read. So on a zone read the offense is effectively seven against six, plus-one in the offense’s favour. The defense’s free men are the two safeties.

One more defender belongs in the count: the nickel back ($), the overhang defender outside the box on the left. With the back beside the quarterback on the left, the zone read’s keep goes left, straight at him, so on the keep side he can play the quarterback and the math there is really seven against seven. That is why offenses pair the read with a quick throw to the slot receiver (a bubble or a glance, the RPO idea): if the $ comes down to take the quarterback, the throw goes behind him, and the slot “blocks” him without touching him.

Expect a zone read, or a run with the quarterback as a threat, likely with that throw attached, and expect it to gain four or five yards before a safety arrives, unless the defense has a plan. Its plans: rotate a safety down at the snap (watch for one creeping toward 8–9 yards before the ball is snapped), or exchange gaps on the read man (the end crashes, a linebacker scrapes to the quarterback, Figure 32.6). If the safeties stay deep and the end sits still, this is the picture the 2019 Ravens punished whenever they got it, and it is a good one for the offense.

TipPredict the play

Drill 3. The force is the target. First-and-10. The offense is in the I-formation and the defense is in a single-high shell, a 4-3 Over with the Sam walked up on the line and the strong safety down outside him, the shape of Figure 32.3. One thing is different: the Z receiver has lined up much closer to the formation than usual. What is the offense planning, and who on the defense has to be ready?

Show the Python
off = [q.moved(w=9.0) if q.key == "Z" else q for q in i_form()]
dfn = over_front() + [D("SS", "SS", 6.0, 8.0, "SS"), D("FS", "FS", 13.0, 0.5, "FS"),
                      D("LCB", "CB", 7.5, -15.0, "CB"), D("RCB", "CB", 7.0, 11.0, "CB")]
p = Play(off, dfn, los=35, to_go=10, title="Drill 3: why is the Z so close?")
p.highlight("Z", color=BALL_RING); p.highlight("SAM", color=WATCH_RING)
f = draw(p, width_in=6.0, lateral=(-18.0, 18.0), window=(-9.0, 15.0))
point_to(f, p, (-4.8, 13.2), (-1.5, 9.0), "tight split", color=style.INK_2, fontsize=6.8)
plt.show()
Figure 32.11: Drill 3: before the snap. 21 personnel in the I-formation; a 4-3 Over with the Sam walked up on the line (orange ring), the strong safety down at about 6 yards outside the tight end and one deep safety. The Z receiver is in a tight split, about 9 yards from the ball instead of out near the numbers.

A crack block on the force, so the cornerback must replace him. The defense’s fit against power depends on the strong safety: he is the force, the man outside the spill. A receiver in a tight split is in perfect position to block down on him at the snap, a crack block (Perimeter Runs and Misdirection), from the side, where the safety is not looking. If the defense spills the kick-out and the force has been cracked, the bounce has nobody outside it.

So the defender who must be ready is the right cornerback. His rule is crack-replace: when the receiver in front of him blocks in, he stops thinking about his deep third and comes up to become the force himself. Many defenses tie this to the split before the snap: a reduced split triggers a “crack!” call, so the corner and the safety both know the crack-replace is on, and some staffs also switch the end man from spill to box so the ball stays inside. A tight split is also the classic tell for crack-toss, where the ball goes straight to the edge the crack has cleared. Watch the corner’s first step after the snap. If it is forward and outside, the defense saw the crack coming. If it is backward, the run is going to the sideline.

Back to the replay

Return to the opening play. The offense ran power to the right; the end man threw himself under the fullback; the back bounced outside and was tackled by a safety who started twelve yards deep. Now you can name every piece of it. The end man was the spill player, and the pile he made was the point: the pulling guard had no lane, and the ball went sideways. The safety who made the tackle was either the force (if he had come down to the edge) or the alley player (if he filled the lane inside the force from depth), and he had been free all along, the defense’s plus-one, never assigned to any blocker. The analyst said “great fit” because every defender between the ball and the sideline did his job and nobody did anyone else’s. Nobody beat a block. The arithmetic did the work.

Takeaways

  • A run fit is an eleven-man plan. Every gap has exactly one owner (gap integrity), and every owner knows how his gap moves when the blocking changes. Two defenders in one gap means an empty gap somewhere else.
  • Force turns the ball back inside. The force defender is a role, not a position: the end, a linebacker, a safety or a corner, depending on the call. The coverage usually decides who is free to be him (safety force in Cover 3, corner force in Cover 2).
  • Spill and box send the ball to opposite places. Spill wrong-arms the kick-out and bounces the ball outside to speed (and dares the offense to log it); box keeps the outside arm free and squeezes the ball inside to the linebackers. Each is a promise about who is waiting, and the alley player fills the lane between the box and the force, coming inside-out as the force comes outside-in.
  • The plus-one is the extra defender, and it usually comes from a safety. Offenses erase it with an extra blocker, a quarterback read or a pass; defenses get it back with rotation, gap exchanges or two-gapping fronts. Count the quarterback when he runs.
  • The light box is a bet, not a mistake. Two-high defenses give up a few yards per carry, four or five before the safeties arrive, to protect against the explosive pass. In 2018–2025 data, each extra box defender cost runs about as much on average as it gave passes, but it bought the passing game far more big plays than it took from the run game, and the run the light box concedes still averages below zero EPA.

Connections

Builds on: Linebackers and the Second Level (keys, flow, fill and scrape: how the second level gets to its gaps), Option Football (the read and the scrape exchange), Gap and Power Runs and Zone Running (the plays these fits answer), Defensive Line Play (setting the edge, fighting a down block, slants), and A First Look at Defense (the box and the shells).

Sets up:

See also (case studies): The Ravens’ Option Run Game, box math with a quarterback who counts as a blocker; and Fangio’s Two-High Revolution and Macdonald’s Answer, the light box as a whole defensive philosophy.

If you want to go deeper: Cody Alexander’s MatchQuarters site and books, the most thorough public writing on how two-high defenses fit the run; Jon Svec’s short essays on defending specific run schemes, spill and box included; Chris B. Brown’s The Art of Smart Football on how run schemes and defenses answer each other; and any broadcast’s end-zone replay of a power run, watched only for the end man and the man outside him.


  1. Jon Svec, “Defending Split Zone” (January 12, 2022): spill players “fight INSIDE the blocker by using a Wrong Arm Technique,” which requires another defender to take the gap outside; a boxing end should “stonewall the Slice Block [split zone’s kick-out] and set the edge,” keeping his “outside arm free”: https://jonsvec.substack.com/p/defending-split-zone. Coaching vocabulary varies: some staffs say squeeze or lever for box technique, and wrong-arm or wrong-shoulder for spill.↩︎

  2. NFL Next Gen Stats: Cover 4 was used on 17.2% of plays in 2025, against a 2018–2024 average of 13.9%: https://www.nfl.com/news/the-coverage-that-turned-the-seahawks-into-super-bowl-winners-and-is-taking-the-nfl-by-storm.↩︎

  3. Ed Raby Jr., “Simplifying Your 2nd Level Run Fits,” American Football Coaches Association (May 9, 2023): a “force/fold” player is “the widest underneath defender outside the run box,” keeping “near-shoulder leverage on the ball carrier,” and the “spill” player fits “inside out on the near hip of the ball carrier”; in Cover 3 the strong safety is a force player, and in Cover 2 the corners are force: https://www.afca.com/simplifying-your-2nd-level-run-fits/. Other staffs use other words for the same jobs. For the two-high version, see Cody Alexander’s MatchQuarters (https://www.matchquarters.com).↩︎

  4. Matt Bowen, a former NFL safety, “Film Study: It’s all about ‘eye discipline’ vs. RG3,” National Football Post (December 13, 2012), on the “High-Hat vs. Low-Hat” run/pass key (the tight end, the tackle and the guard-center-guard “triangle”), and how play-action punishes a defender whose eyes leave his key: https://www.nationalfootballpost.com/film-study-its-all-about-eye-discipline-vs-rg3.↩︎

  5. James Reber, Next Gen Stats, “NFL trend watch: heavy personnel” (February 2026): offenses used fewer than three wide receivers on 41.7% of plays in 2025: https://www.nfl.com/news/nfl-trend-watch-heavy-personnel-could-shape-super-bowl-lx-showdown-between-patriots-and-seahawks.↩︎

  6. NFL Next Gen Stats, split-safety coverage rate: 32.9% (2018), 40.4% (2024), 42.0% (2025): https://www.nfl.com/news/the-coverage-that-turned-the-seahawks-into-super-bowl-winners-and-is-taking-the-nfl-by-storm.↩︎

  7. This book’s calculation from nflverse play-by-play joined to participation data (defenders_in_box), regular-season designed runs (quarterback scrambles and kneels excluded): six or fewer in the box on 37–40% of designed runs each season from 2018 to 2022, 43% in 2023, 58% in 2024 and 55% in 2025. The box count comes from Next Gen Stats through 2022 and from FTN charting from 2023, so part of the change may be how the box is counted; the jump from 2023 to 2024 is within the FTN years.↩︎

  8. Fangio (born 1958): San Francisco defensive coordinator 2011–2014, Chicago defensive coordinator 2015–2018, Denver head coach 2019–2021, Eagles consultant 2022, Miami defensive coordinator 2023, Philadelphia defensive coordinator from 2024 (still in 2026: https://www.profootballrumors.com/2026/02/2026-nfl-offensive-defensive-coordinator-search-tracker). His first NFL job was Saints linebackers coach in 1986, so he spent 32 NFL seasons as an assistant before Denver hired him in January 2019: https://en.wikipedia.org/wiki/Vic_Fangio. Staley worked under Fangio in Chicago and Denver before running the Rams’ defense (2020) and coaching the Chargers (2021–2023); Diante Lee, “Checking in on the Vic Fangio coaching tree after Week 1 of the 2021 NFL season,” PFF (September 15, 2021), on Staley, Joe Barry and Sean Desai carrying the scheme: https://www.pff.com/news/nfl-vic-fangio-coaching-tree-week-1-2021.↩︎

  9. EJ Smith, “Eagles run defense … Vic Fangio,” Philadelphia Inquirer (September 19, 2024): a light box forces the linemen to “win at the point of attack and, at times, ‘steal’ back gaps”: https://www.inquirer.com/eagles/eagles-run-defense-vic-fangio-jalen-carter-falcons-bijan-robinson-20240919.html.↩︎

  10. Next Gen Stats (Reber), same article as above: defenses played base on 29.7% of plays in 2025, against a low of 20.5% in 2023.↩︎

  11. This book’s calculation, same filters as the chart, both eras pooled: designed runs averaged −0.03, −0.05, −0.09 and −0.15 EPA against 5-or-fewer, 6, 7 and 8-or-more defenders in the box (success rates 41%, 40%, 37% and 34%; 5.1, 4.8, 4.6 and 4.2 yards per carry; about 1,600, 21,800, 20,100 and 6,700 runs). Dropbacks averaged +0.06, +0.08, +0.12 and +0.16 EPA.↩︎

  12. This book’s calculation, same filters as the chart, both eras pooled (the NGS and FTN eras agree within two percentage points on every rate): dropbacks gaining 20 or more yards, 7%, 8%, 11% and 12% against 5-or-fewer, 6, 7 and 8-or-more in the box; designed runs gaining 10 or more, 13%, 12%, 12% and 11%. Share of plays that were designed runs: 17%, 43%, 55% and 64%.↩︎

  13. “Seattle Cover 3 defense,” Wikipedia (the scheme of Pete Carroll and Dan Quinn; Seattle led the NFL in scoring defense from 2012 to 2015; Thomas as the post safety, Chancellor in the box): https://en.wikipedia.org/wiki/Seattle_Cover_3_defense; “Legion of Boom,” Wikipedia: https://en.wikipedia.org/wiki/Legion_of_Boom.↩︎

  14. EJ Smith, Philadelphia Inquirer, September 19, 2024 (cited above): six or fewer in the box on “73.5% of the time, which is the NFL’s third-highest rate,” written after the Eagles’ Week 2 loss to Atlanta.↩︎

  15. This book’s calculation from nflverse play-by-play and participation data, 2024 regular season, opponents’ designed runs: the Eagles faced six or fewer in the box on 66% of them (third-highest rate; league 58%) and allowed −0.18 EPA per designed run, the lowest of the 32 defenses.↩︎

  16. This book’s calculation from nflverse play-by-play and participation data, regular seasons, opponents’ designed runs: the share of runs Fangio’s defenses faced with six or fewer in the box ranked 5th (Denver 2019), 2nd (2020), 3rd (2021), 2nd (Miami 2023), 3rd (Philadelphia 2024) and 3rd (2025) of 32 defenses; by average box count, 7th, 2nd, 3rd, 10th, 5th and 5th lightest. EPA per designed run allowed ranked 1st in 2024 and 7th in 2025. Super Bowl LIX, Eagles 40, Chiefs 22: https://en.wikipedia.org/wiki/Super_Bowl_LIX.↩︎

  17. Olivia Reiner, “Eagles’ Jalen Carter might not get holding calls, but his impact is felt,” Philadelphia Inquirer (December 3, 2024), on Carter’s double teams, Milton Williams’s pressure rate among defensive tackles, and Fangio on Jordan Davis: https://www.inquirer.com/eagles/eagles-jalen-carter-jordan-davis-defensive-line-20241203.html.↩︎

  18. “Ravens break single-season team rushing record,” NFL.com (3,296 yards, breaking the 1978 Patriots’ 3,165): https://www.nfl.com/news/ravens-break-single-season-team-rushing-record-0ap3000001092761; Jackson’s 1,206 rushing yards and unanimous MVP: https://en.wikipedia.org/wiki/2019_Baltimore_Ravens_season. The era is closed: John Harbaugh was fired in January 2026 and became the Giants’ head coach: https://en.wikipedia.org/wiki/2026_NFL_season.↩︎

  19. This book’s calculation from nflverse play-by-play and participation data (Next Gen Stats box counts), 2019 regular season, designed runs: Baltimore faced seven or more in the box on 65% (league 62%); EPA per designed run +0.10 against seven (league −0.10) and +0.04 against eight or more (league −0.13); Baltimore led the league at +0.09 EPA per designed run overall. Jackson: 120 designed runs, 7.1 yards per carry.↩︎

  20. NFL.com, “Saquon Barkley becomes ninth player to rush for 2,000 yards in a season”: https://www.nfl.com/news/saquon-barkley-becomes-ninth-player-to-rush-for-2000-yards-in-a-season.↩︎

  21. This book’s calculation from nflverse play-by-play, participation and FTN charting, 2024 regular season, designed runs excluding quarterback sneaks (FTN is_qb_sneak): Philadelphia ran into six or fewer in the box on 61% (league 59%), averaging 5.4 yards (league 4.7) with 14% gaining 10 or more yards (league 12%); against seven or more, 4.7 yards (league 4.0). Barkley averaged 5.9 yards against six or fewer.↩︎