The Language of the Run Game: Gaps, Techniques, and Blocks

The words coaches use for the spaces in a line, where every defender stands, and what every blocker does, and why each word exists

Show the Python (shared helpers for this chapter’s diagrams)
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
from gridiron.play import draw_marker

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
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 line(labels="full"):
    """The five offensive linemen, labelled LT..RT ("full") or with one letter, T G C G T ("short")."""
    short = {"LT": "T", "LG": "G", "C": "C", "RG": "G", "RT": "T"}
    return [p.moved(label=(p.key if labels == "full" else short[p.key])) for p in offense("singleback")
            if p.key in OL_KEYS]


def te(side=1, key=None, label=None):
    """An in-line tight end: Y on the right, U on the left."""
    key = key or ("Y" if side > 0 else "U")
    return O(key, "TE", -0.7, side * 4.8, label or key)


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 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, 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.5, 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=7, shrink=7):
    """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,
                    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=9):
    """A gap letter or hole number 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.22", fc=style.SURFACE, ec=color, lw=1.0))


def pair_oval(fld, p, d, w, width, height=2.5, color=GREEN):
    """A faint oval around a double team (two blockers and their defender)."""
    x, y = _P(fld, p, d, w)
    fld.ax.add_patch(Ellipse((float(x), float(y)), width, height, fc=color, alpha=0.22, ec="none", zorder=1.5))
    fld.ax.add_patch(Ellipse((float(x), float(y)), width, height, fc="none", ec=color, lw=1.6,
                             ls=(0, (4, 2)), zorder=1.6))


def spot(fld, p, d, w, color=style.THIRD, ms=9):
    """Mark a point (the point of attack, an aiming 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=9)


def shade_box(fld, p, w0, w1, d1=6.5, d0=-0.2, color=style.THIRD, alpha=0.08, label=None):
    """Shade the box (or any rectangle) from width w0 to w1 and depth d0 to d1."""
    (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=(0, (3, 2)), zorder=0.8))


def dashed(fld, p, pts, color=style.THIRD, lw=1.6, dash=(0, (3, 2.2)), end="arrow"):
    """A dashed 'option' 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]))
    fld.ax.plot(xs[:-1] if end == "arrow" else xs, ys[:-1] if end == "arrow" else ys, color=color, lw=lw,
                ls=dash, zorder=6)
    if end == "arrow":
        fld.ax.add_patch(FancyArrowPatch((xs[-2], ys[-2]), (xs[-1], ys[-1]), arrowstyle="-|>",
                                         mutation_scale=10, color=color, lw=lw, zorder=6))


def play_arrow(fld, p, d, w0, w1, text, fontsize=7.5):
    """A broad 'the play goes this way' arrow at depth d, from w0 to w1."""
    (x0, y0), (x1, y1) = _P(fld, p, d, w0), _P(fld, p, d, w1)
    fld.ax.add_patch(FancyArrowPatch((x0, y0), (x1, y1), arrowstyle="-|>", mutation_scale=14,
                                     color=style.OFFENSE, lw=2.0, zorder=3))
    xm, ym = _P(fld, p, d + 0.9, (w0 + w1) / 2)
    fld.ax.text(xm, ym, text, fontsize=fontsize, color=style.OFFENSE_DARK, ha="center", va="center", zorder=4,
                fontweight="bold")


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."""
    fld = p.draw(width_in=width_in, ax=ax, **kw)
    clean(fld.ax)
    return fld


# --- a front, labelled by technique number ---------------------------------------------------------
def front(spec, lbs=(), safeties=()):
    """Defensive linemen from (key, technique, side) triples, labelled with their technique number,
    plus (key, d, w, label) linebackers and safeties."""
    out = [D(k, "DL", 1.0, T(t, s), t) for k, t, s in spec]
    out += [D(k, "LB", d, w, lab) for k, d, w, lab in lbs]
    out += [D(k, "S", d, w, lab) for k, d, w, lab in safeties]
    return out


def cov_labels(fld, p, status, d=-2.0, fontsize=6.6):
    """'covered' / 'uncovered' under each offensive lineman."""
    for k, v in status.items():
        say(fld, p, d - (0.95 if v == "uncovered" else 0.0), p.players[k].w, v, fontsize=fontsize,
            color=style.DEFENSE_DARK if v == "covered" else GREEN)


# --- frame strips (PDF) and video (web) for the simulated combo block --------------------------------
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=(), enter=()):
    """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 whole at the snap ...
    ids = set(first["_id"]) | {"football"}
    inside = cur[cur["x"].between(play.los + window[0], play.los + window[1]) & cur["y"].between(ylo, yhi)]
    ids |= set(inside["_id"]) & set(enter)                         # players allowed to walk into the picture
    shown = cur[cur["_id"].isin(ids) | (cur["side"] == "ball")]    # ... stay in every frame (clipped at the edge)
    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)), 0.95, fc="none", ec=col, lw=1.6, zorder=7))
    for patch in ax.patches:
        patch.set_clip_on(True)
    return fld


def strip(play, times, lateral, window, notes=None, rings=(), ncols=4, width_in=6.5, after=None, enter=()):
    """Numbered frame strip with a fixed, box-sized window, so markers stay legible in print."""
    df = tracking(play)
    nrows = int(np.ceil(len(times) / 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.55 if notes else 0.25))))
    for ax in axes.flat[len(times):]:
        ax.axis("off")
    for i, (ax, t) in enumerate(zip(axes.flat, times)):
        fld = panel(ax, play, df, t, lateral, window, rings, enter)
        if after:
            after(fld, t)
        ax.set_title(f"{i + 1}.  " + ("snap" if abs(t) < 1e-6 else f"{t:+.2f} s".rstrip("0")),
                     fontsize=8.5, 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.2, color=style.INK)
    fig.tight_layout(h_pad=1.3 if notes else 0.6, w_pad=0.5)
    return fig


def video(play, times, lateral, window, notes=None, rings=(), width_in=5.2, after=None, enter=()):
    """Web version of the strip: the same panel at every frame, with the strip's notes as captions."""
    import shutil
    from matplotlib import animation
    from IPython.display import HTML, display
    df = tracking(play)
    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.4))
    tmap = df.groupby("frameId")["time"].first()

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

    anim = animation.FuncAnimation(fig, update, frames=sorted(df["frameId"].unique()), 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(play, times, **kw):
    """Video on the website; a numbered, captioned frame strip in the PDF."""
    if pdf_build():
        strip(play, times, **kw)
        plt.show()
    else:
        kw.pop("ncols", None)
        video(play, times, **kw)

The replay rolls, and the analyst draws on the screen. “Look at this. They’ve got a 3-technique over the right guard, and they run right at him. The guard and tackle double-team him, one of them climbs to the Mike, the fullback kicks out the end, and the back hits the C gap untouched.” You nodded, because he sounded certain. But almost every noun in that sentence was a word nobody ever taught you: 3-technique, double team, climbs, kicks out, the end, the C gap. This chapter teaches them, and near the end you will read that sentence again and understand every word. It is the vocabulary the rest of the run game is written in, and it is smaller than it sounds: a handful of names for spaces, a numbering for where a defender stands, and eight verbs for what a blocker does. Each one exists because it solves a problem. Learn the problems and the words stick.

You’ll be able to:

How to read the diagrams. Offense is blue circles, defense orange squares. Left and right always mean the offense’s left and right, and plays are drawn going up the page. LT, LG, C, RG and RT are the five offensive linemen (in the small block diagrams, just T, G and C); Q is the quarterback, R the running back, F a fullback, Y and U are tight ends on the right and left, and X, Z and H are wide receivers (H in the slot). Defensive linemen are labelled with their technique number, which this chapter teaches; M, W and S are the Mike, Will and Sam linebackers you met in The Twenty-Two; $ is the nickel back, CB a cornerback, and FS and SS the safeties, as in A First Look at Defense. Lines ending in a short bar are blocks; arrows are paths; the thick dark arrow is the ball carrier.

Why the run game needs its own words

A running play lasts about three seconds and involves twenty-two people colliding in a space about fifteen yards wide. The people inside it have to talk about it in two very different moments. Before the snap, a center has maybe ten seconds to tell four other linemen who is blocking whom against a defense that is still moving. (He usually starts by naming one linebacker as “the Mike,” the reference point every lineman counts from; that call, Mike identification, is taught in Pass Protection.) Later, in the film room, a line coach has to explain why a play that gained twelve yards last week lost two today. Both conversations need words that are short, unambiguous, and shared by everyone in the room.

So football built a vocabulary for exactly three things:

  1. The spaces in the line where a runner can go (gaps and holes).
  2. Where each defender stands relative to the blockers (technique numbers).
  3. What each blocker does (a short list of named blocks).

Nearly every sentence about the run game, from a high-school coach’s whistle to a network analyst’s telestrator, is built from those three sets of words. One more idea glues them together: counting. Run blocking is in the end an arithmetic problem, blockers against defenders, and the last third of this chapter is about that arithmetic.

Gaps: the spaces between blockers

Start with the line itself. When an offense breaks the huddle, its five linemen stand side by side, a little more than an arm’s length apart (the space between them is the lineman’s split). The spaces between them, and the space outside the last man, are where a running back can go. Each space has a letter.

Show the Python
off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("RB", "RB", -7.0, 0, "R")]
p = Play(off, None, los=35, to_go=None)
fld = draw(p, width_in=5.6, lateral=(-8.5, 9.5), window=(-8.5, 4.6))
for w, g in [(-0.8, "A"), (0.8, "A"), (-2.4, "B"), (2.4, "B"), (-4.4, "C"), (4.0, "C"), (5.95, "D")]:
    gap_tag(fld, p, 1.0, w, g)
for w in (-0.8, 0.8, -2.4, 2.4, 4.0):                          # faint lines between the blockers
    x, y = _P(fld, p, np.array([-1.5, 0.3]), np.array([w, w]))
    fld.ax.plot(x, y, color=GREEN, lw=0.8, ls=(0, (2, 2)), alpha=0.6, zorder=2)
say(fld, p, 3.1, 6.3, "the tight end\nadds a D gap", color=GREEN, fontsize=7)
say(fld, p, 3.1, -5.6, "no tight end:\nC is the last gap", color=GREEN, fontsize=7)
say(fld, p, -2.2, 4.8, "Y = tight end", fontsize=7)
plt.show()
Figure 15.1: Gaps are lettered outward from the center, the same on both sides: A between the center and a guard, B between a guard and a tackle, C outside a tackle. A tight end (Y) on the line adds one more gap outside himself, the D gap, on his side only. With no tight end on the left, that side ends at the C gap.

A gap is the space between two adjacent players on the line of scrimmage, named by a letter counted outward from the center:

  • The A gaps are on either side of the center, between the center and each guard.
  • The B gaps are between each guard and the tackle beside him.
  • The C gaps are just outside each tackle (between the tackle and a tight end, if there is one).
  • The D gap is outside a tight end. It exists only on a side with a tight end on the line.

There is one A, one B and one C gap on each side, so an offense with no tight end has six gaps, and every tight end on the line adds one more. Some coaches keep going (an “E gap” outside a second tight end or a wing), but A to D covers almost everything you will hear on a broadcast.

Why letters, and why from the defense’s point of view? Gap letters are mostly the defense’s language. A run defense’s first job is to make sure that every gap has a defender responsible for it, so that wherever the ball carrier goes, somebody is already there. Coaches call that a defender’s gap responsibility: “you have the B gap.” Letters are fast to shout and the same on both sides of the ball, which is why a linebacker can say “A gap, A gap!” and every teammate knows he means the space next to the center. (How defenses divide up the gaps, and what happens when a defender leaves his, is Run Fits and Box Math.)

That point leads straight to the first piece of run-game arithmetic, which you first met in Formation Rules: every player the offense puts on the line creates a gap the defense has to fill. Add a tight end and there are seven gaps instead of six; add a second tight end and there are eight. A defense that wants a defender for every gap needs one more defender near the ball for every blocker the offense attaches to its line. That is a big part of why offenses use tight ends in the run game at all, and why the personnel an offense sends on the field changes how many defenders the defense has to keep close.

CautionCommon misconception

“The A gap is a spot on the field.” It is not. A gap is defined by the players on either side of it, so it moves when they move. If the center and right guard both step two yards to their right at the snap, the right A gap moves two yards to the right with them. That sounds pedantic, but it matters as soon as you watch a zone run in 03-02, where the whole line moves sideways together and the gaps slide along the line with it. Gaps also stretch and shrink: a lineman who takes a wider split before the snap makes the gaps on either side of him wider, and defenses watch splits for exactly that reason.

Holes: the offense’s numbers

The offense has its own way of naming the same spaces, a separate system built for a different job: calling a play in the huddle.

Show the Python
off = line("full") + [te(+1), te(-1), O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.5, 0, "3"),
                      O("RB", "RB", -7.0, 0, "2")]
p = Play(off, None, los=35, to_go=None)
go_to(p, "RB", (2.6, 4.0), "run", via=[(-4.6, 1.5), (-1.3, 4.0)])
fld = draw(p, width_in=5.6, lateral=(-9.5, 9.5), window=(-8.6, 4.6))
for w, n in [(0.8, "0"), (2.4, "2"), (4.0, "4"), (5.95, "6"), (7.7, "8"),
             (-0.8, "1"), (-2.4, "3"), (-4.0, "5"), (-5.95, "7"), (-7.7, "9")]:
    gap_tag(fld, p, 1.0, w, n, color=style.OFFENSE_DARK)
say(fld, p, 3.2, 4.6, "even numbers: right", color=style.OFFENSE_DARK, fontsize=7)
say(fld, p, 3.2, -4.6, "odd numbers: left", color=style.OFFENSE_DARK, fontsize=7)
point_to(fld, p, (-6.6, 6.0), (-4.8, 1.6), "\"24\": the 2-back\nthrough the 4 hole", fontsize=7)
say(fld, p, -5.6, -4.0, "backs numbered too:\nQ = 1, tailback = 2,\nfullback = 3", fontsize=6.8)
plt.show()
Figure 15.2: One common hole-numbering system, drawn with two tight ends (U and Y) so both sides match: counting outward from the center, the holes on the right get even numbers (0, 2, 4, 6, 8) and the holes on the left get odd numbers (1, 3, 5, 7, 9). The backs have numbers too. A two-digit call names the ball carrier, then the hole: ‘24’ sends the tailback (the 2-back) through the 4 hole, just outside the right tackle. The 8 and 9 holes are the widest, outside the tight ends: runs around the end. Many teams flip odd and even, or number the linemen instead of the spaces.

In hole numbering, every place a run can go gets a digit. In the most common version, the holes are counted outward from the center with even numbers on one side and odd numbers on the other (in Figure 35.7, even to the right). The backs get digits too: in one classic scheme, built for the four backs of the old T-formation, the quarterback is 1, the fullback 3, and the halfbacks 2 and 4 (2 on the left, 4 on the right; in an I-formation the tailback is the 2).1 Put the two together and a run call is just two digits: “24” means the 2-back carries the ball through the 4 hole. A coach can add a word for the blocking scheme (“24 Power,” “32 Trap”) and the whole play fits in one breath.

Why it exists. Before radio helmets and wristbands, a play had to be called in a huddle in a few seconds and remembered by eleven people. A numbering system lets one short code cover hundreds of plays: any back, any hole, any blocking scheme. Linemen learn rules for each scheme (“on 24 Power, the play-side tackle blocks down”), so the number tells them which rule applies and which way to apply it.

The catch. Numbering is a dialect, not a standard. Some teams number the gaps, as in the picture; others number the linemen, so that the “0 hole” is the center himself and the “2 hole” is wherever the right guard was. Some put the odd numbers on the right. And many modern offenses barely use hole numbers in their run calls at all, because their most common runs do not have one hole. On a zone run, as you will see in 03-02, the line steps together and the runner picks the hole after the snap; a call like “outside zone right” says where the play starts, not where it ends. That is why you will hear NFL coaches name runs by scheme and direction far more often than by number. (How whole playbooks name things is in Offensive Systems and Their Languages.)

NoteMadden vs. real life

Madden’s play art draws the running back’s path to one spot, and the game rewards you for hitting it. In a real NFL run the drawn path is only the plan: on zone runs, one of the two great families you will meet at the end of this chapter, the hole is decided after the snap by how the defense reacts. A hole number tells you where the play is designed to go. Whether it goes there is up to eleven defenders.

Play side, backside, and the point of attack

Three more words describe direction, and you need them before the blocks make sense.

Show the Python
off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.5, 0, "F"), O("RB", "RB", -7.0, 0, "R")]
dfn = front([("LE", "5", -1), ("LT_", "1", -1), ("RT_", "3", 1), ("RE", "9", 1)],
            lbs=[("WILL", 4.5, -2.8, "W"), ("MIKE", 4.5, 1.0, "M"), ("SAM", 4.2, 6.0, "S")])
p = Play(off, dfn, los=35, to_go=None)
go_to(p, "C", (0.35, -0.55), via=[(-0.3, -0.25)])                # drives the 1 to the left ...
go_to(p, "LT_", (2.3, -2.3), "path", speed=1.2)                  # ... (orange: where he is pushed)
go_to(p, "RG", (0.35, 2.3), via=[(-0.4, 1.95)])                  # drives the 3 to the right
go_to(p, "RT_", (2.3, 4.0), "path", speed=1.2)
go_to(p, "FB", (3.5, 1.25), "block", via=[(-2.7, 1.45), (1.6, 1.3)], speed=5.0)
go_to(p, "RB", (1.9, 0.45), "run", via=[(-5.7, 0.95), (-3.2, 0.95), (-0.6, 0.75)])
p.highlight("RB")
fld = draw(p, width_in=5.8, lateral=(-10.5, 10.5), window=(-8.6, 7.5))
shade_box(fld, p, 0.0, 10.4, d0=-8.5, d1=7.4, color=style.OFFENSE, alpha=0.06)
spot(fld, p, 1.0, 0.8, color=style.THIRD, ms=11)
say(fld, p, 5.9, 7.9, "PLAY SIDE", color=style.OFFENSE_DARK, fontsize=8, weight="bold")
say(fld, p, 5.9, -7.9, "BACKSIDE", color=style.INK_2, fontsize=8, weight="bold")
point_to(fld, p, (-3.2, 6.8), (1.0, 0.8), "point of attack:\nthe right A gap", color=GREEN, fontsize=7, shrink=4)
say(fld, p, -6.4, 4.2, "F leads on the M,\nR follows", fontsize=7)
plt.show()
Figure 15.3: A lead run to the right. The shaded half of the formation is the play side, the half the run is aimed at; the other half is the backside. The point of attack (green X) is the spot on the line where the play is designed to hit: here, the right A gap, between the center and the right guard. No defensive lineman stands in it (the 1 is on the center’s other shoulder, the 3 outside the guard), so the nearest defender is the Mike linebacker behind it. Two blocks widen it: the center drives the 1 to his left and the right guard drives the 3 to his right (orange arrows show where each defender is pushed). The fullback (F) leads through onto the Mike, and the running back (R) follows him. Only the blocks that make the hole are drawn.

The play side (often written playside) is the half of the formation the run is aimed at; the backside is the other half, away from the play. The point of attack is the exact spot on the line where the play is designed to hit: in Figure 15.3, the right A gap. Broadcasters abbreviate it “the POA” or say “the point.”

Notice why the play aims there. The point of attack is chosen for who is standing near it and how he can be blocked. Here the right A gap has no defensive lineman in or beside it, so the nearest defender is a linebacker four or five yards away: coaches call that a bubble, and a lead play loves it, because the fullback can get to the linebacker before the linebacker gets to the hole. Often, though, the chosen spot has a defender standing right in it. Then the blocks are what empty it: the linemen move the man who owns that gap out of it, and the run goes into the space they made. On a designed run the hole is mostly made, not found.

Do not confuse the play side with the strong side. The strong side is a fact about the formation (the side with the tight end, or with more players), fixed before the snap. The play side is a fact about the play, and offenses run away from their strong side all the time, precisely because defenses load up toward it.

Why the distinction matters: blockers have completely different jobs on the two sides. On the play side their job is to make the hole: move defenders, wall them off, create space at the point of attack. On the backside their job is to stop the defenders on that side from chasing the play down from behind. Those backside defenders do not need to be knocked back; they only need to be kept out of the way for a second or two. As you are about to see, there are different blocks for each job, and the side a block is on tells you most of what it is trying to do.

Technique numbers: where the defender stands

Now turn to the defense. Before an offensive lineman can block anyone, he needs to know exactly where the defender in front of him is standing, because a defender on his left shoulder and one on his right shoulder are different problems. Saying “the tackle’s a bit outside the guard” is too slow and too vague. So football gave every spot along the line a number.

Show the Python
fig, ax = plt.subplots(figsize=(6.6, 2.5))
SP = 2.4                                            # exaggerated split, for room to write
xs = {"U": -3 * SP, "LT": -2 * SP, "LG": -SP, "C": 0.0, "RG": SP, "RT": 2 * SP, "Y": 3 * SP}
ax.add_patch(Rectangle((-11.5, -2.9), 21.1, 7.1, fc=style.TURF, ec=style.BASELINE, lw=1, zorder=0))
ax.plot([-11.5, 9.6], [0.75, 0.75], color=style.OFFENSE_DARK, lw=1.2, alpha=0.6, zorder=1)
ppy = 6.6 * 72 / 20.0 * 0.85
for k, x in xs.items():
    draw_marker(ax, x, 0.0, "off", k, ppy, r=0.62)
shade_row, head_row = 1.75, 3.25
tech = []                                           # (label, x, row)
for s in (1, -1):
    tech += [("1", s * 0.8, shade_row), ("2i", s * (SP - 0.8), shade_row), ("2", s * SP, head_row),
             ("3", s * (SP + 0.8), shade_row), ("4i", s * (2 * SP - 0.8), shade_row), ("4", s * 2 * SP, head_row),
             ("5", s * (2 * SP + 0.8), shade_row), ("7", s * (3 * SP - 0.8), shade_row), ("6", s * 3 * SP, head_row),
             ("9", s * (3 * SP + 0.8), shade_row)]
tech.append(("0", 0.0, head_row))
for lab, x, row in tech:
    ax.plot([x, x], [0.75, row - 0.45], color=style.DEFENSE, lw=0.7, ls=(0, (1.5, 1.5)), alpha=0.8, zorder=2)
    draw_marker(ax, x, row, "def", lab, ppy, r=0.36)
for s in (1, -1):
    for x, g in [(SP / 2, "A"), (1.5 * SP, "B"), (2.5 * SP, "C"), (3.5 * SP, "D")]:
        ax.text(s * x, -0.05, g, ha="center", va="center", fontsize=10, color=GREEN, fontweight="bold", zorder=5)
ax.text(-11.3, head_row, "head-up\n(even)", ha="left", va="center", fontsize=7.2, color=style.INK_2)
ax.text(-11.3, shade_row, "shaded\n(odd, or i)", ha="left", va="center", fontsize=7.2, color=style.INK_2)
ax.text(-1.0, -1.55, "gaps (letters): A next to the center, then B, C and D outward",
        ha="center", va="center", fontsize=7.5, color=GREEN)
ax.text(-1.0, -2.35, "line of scrimmage = the blue line; every defender here is about a yard off the ball",
        ha="center", va="center", fontsize=7, color=style.INK_2)
ax.set_xlim(-11.6, 9.7); ax.set_ylim(-3.0, 4.3); ax.set_aspect("equal"); ax.axis("off")
fig.patch.set_facecolor(style.SURFACE)
plt.show()
Figure 15.4: The technique chart. The offensive line is drawn with extra-wide spacing so every number has room; in a real game all these alignments are crammed into the 10 or so yards between the tight ends, about a yard off the ball. Head-up alignments (top row) take even numbers: 0 on the center, 2 on a guard, 4 on a tackle, 6 on a tight end. Shaded alignments (lower row) take odd numbers on a lineman’s outside shoulder (1, 3, 5, 9) or an ‘i’ for an inside shoulder (2i, 4i); the inside shoulder of a tight end is a 7. Green letters are the gaps from earlier: each gap holds one or two shaded alignments.

A technique (or alignment number) says where a defensive lineman lines up relative to the offensive linemen. You met two of its words, head-up and shaded, and the 3-technique in The Twenty-Two; here is the full system. It rests on two ideas:

  • A defender lined up directly across from a blocker, nose to nose, is head-up on him, and gets an even number: 0 head-up on the center, 2 on a guard, 4 on a tackle, 6 on a tight end.
  • A defender on one of a blocker’s shoulders is in a shade. On the outside shoulder he gets the odd number after that blocker’s even one: 1 on the center’s shoulder, 3 on the guard’s outside shoulder, 5 on the tackle’s. On an inside shoulder he gets the blocker’s even number plus an “i”: 2i on the guard’s inside shoulder, 4i on the tackle’s.

The numbers are mirrored: a 3-technique can be on the left guard or the right guard, and the caption or the context tells you which. The pattern breaks at the tight end: in the most common version, a defender on the tight end’s inside shoulder is a 7 (not a “6i”), and anything outside him is a 9. Systems disagree here more than anywhere else. Some swap the 6 and the 7, some use an 8 when two tight ends line up on the same side, and many use “wide 9” for an end lined up well outside the tight end.2

Table 15.1: Where each shaded alignment lives. Outside a tight end, everything is a 9 or wider.
Gap Alignments that sit in it Typical player
A 1, 2i (and a 0 can play either A gap) nose tackle, “shade” nose
B 3, 4i 3-technique tackle; 3-4 defensive end
C 5, 7 defensive end
D 9 defensive end or outside linebacker on the edge

That table is the reason the system exists. A shaded defender is usually responsible for the gap he is shaded into. A 3-technique sits in the B gap and, in most defenses, owns it; a 1-technique owns the A gap he is sitting in. So the alignment number is not just a location: it is a strong hint about the defender’s job. Head-up defenders are different. A 0 or a 4 is often asked to control the blocker in front of him and then fill whichever gap the ball goes to, on either side. That style is called two-gapping, and it is taught in Defensive Line Play.

If a 3 and a 4i both sit in the B gap, why does anyone care which one it is? Because the number says whose shoulder he is on, and so which blocker has a man in his face. A 3 is on the guard; a 4i is on the tackle. Same gap, different blocker occupied, and as the next section shows, that decides who is free to help and who has to block him. That is also how to tell them apart in a game. The real distances are tiny: linemen usually leave a gap of about two feet between themselves and the next man,3 so a whole B gap is two or three feet wide and a 3 and a 4i stand about a foot apart. Don’t try to place a defender in the gap; ask which lineman’s shoulder he is lined up on. The angle that shows it best is the end-zone replay, shot from behind the offense straight down the line; the high sideline camera of a live broadcast flattens the line and hides it.

Where the numbers came from. The system is usually credited to Paul “Bear” Bryant, but the better-documented story gives it to Bum Phillips, who, by his hometown paper’s account, devised it while coaching at Nederland High School in Texas in the early 1950s, and who joined Bryant’s staff at Texas A&M in 1957. Bryant himself credited Phillips. Before it, every staff used its own code words for alignments, so a lineman who changed schools had to learn a new language.4 Phillips, the Stetson-wearing Texan who later coached the Houston Oilers, liked things simple, and the numbers stuck because they are simple: two rules, ten digits and an “i”, and a defensive coordinator can describe an entire line in a breath.

The numbers that became position names

A few technique numbers are used so often that they turned into names for positions:

  • The 3-technique is the defensive tackle on a guard’s outside shoulder. In a four-man line he is usually the best pass rusher on the inside, because his alignment puts him one-on-one with a guard in the B gap, with room to shoot past him. When analysts call a player “a 3-technique” they mean that job and that body type: quick, explosive, penetrating. Aaron Donald, whom you met in The Twenty-Two, was the archetype.
  • The 5-technique is on the tackle’s outside shoulder. In a 3-4 defense it became the name for the defensive end: a big, long player who can hold off the tackle and still close the C gap.
  • The 4i-technique sits on the tackle’s inside shoulder, in the B gap. It is a favorite alignment for the ends of modern three-man fronts. It squeezes the B gap from the inside, it is hard for the tackle to get outside of (he is already inside the tackle’s body), and because he can play off either the guard or the tackle, he muddles which of those two should block him and which should go to the linebacker.
  • The 0 and 1 are the nose. A 0 is head-up on the center; a 1, often called a shade nose, sits on one of the center’s shoulders. Both are usually the heaviest men on the field (the nose tackle of 01-03).

Once you know the numbers, a whole front becomes a string you can say out loud.

Show the Python
def two_fronts():
    four = front([("LE", "5", -1), ("LT_", "1", -1), ("RT_", "3", 1), ("RE", "9", 1)],
                 lbs=[("WILL", 4.5, -2.8, "W"), ("MIKE", 4.5, 1.2, "M"), ("SAM", 4.3, 6.4, "S")])
    tite = front([("LE", "5", -1), ("LD", "4i", -1), ("NT", "0", 1), ("RD", "4i", 1), ("RE", "9", 1)],
                 lbs=[("WILL", 4.6, -1.8, "W"), ("MIKE", 4.6, 1.8, "M")])
    tite = [q.moved(w=q.w - 0.5) if q.key == "LE" else q for q in tite]   # the edge a step wider
    return [("A four-man front: 5, 1, 3, 9", four), ("A five-man front: 5, 4i, 0, 4i, 9", tite)]


def front_play(dfn):
    return Play(line("full") + [te(+1)], dfn, los=35, to_go=None)


fig, axes = plt.subplots(1, 2, figsize=(6.6, 2.6))
for ax, (ttl, dfn) in zip(axes, two_fronts()):
    p = front_play(dfn)
    f = draw(p, ax=ax, lateral=(-6.9, 7.3), window=(-1.9, 6.0), title=False)
    ax.set_title(ttl, fontsize=8.8, loc="left", color=style.INK, fontweight="bold")
fig.tight_layout(w_pad=0.8)
plt.show()
Figure 15.5: Two fronts, read as numbers from left to right. Left: four linemen in a 5, a 1 (shaded on the center’s left shoulder), a 3 (on the right guard’s outside shoulder) and a 9 (outside the tight end), with three linebackers behind them. Right: five men on the line in a 5, a 4i, a 0, a 4i and a 9, with two linebackers. The names and logic of these fronts are taught in Part 5; here they are just practice in reading the numbers.

Read Figure 15.5 from left to right and you can describe each front without a single name: “five, one, three, nine” and “five, four-i, zero, four-i, nine.” Coaches do exactly that. The right-hand front has a name, the tite front, and a story (why so many NFL defenses adopted it to stop inside runs) that belongs to Odd and Hybrid Fronts. The four-man front on the left is one of the even fronts in 05-02. You do not need either name yet. You need the numbers, because the numbers are what the offensive line reads.

Covered and uncovered linemen

Here is the first thing an offensive lineman does with those numbers. Before every snap, each lineman asks a one-word question: am I covered?

Show the Python
COVERS = [{"LE": "LT", "LT_": "C", "RT_": "RG", "RE": "Y"},
          {"LE": "LT", "LD": "LT", "NT": "C", "RD": "RT", "RE": "Y"}]
fig, axes = plt.subplots(2, 1, figsize=(6.0, 5.4))
for ax, (ttl, dfn), cov in zip(axes, two_fronts(), COVERS):
    p = Play(line("full") + [te(+1)], dfn, los=35, to_go=None)
    f = draw(p, ax=ax, lateral=(-7.0, 7.4), window=(-2.6, 5.4), title=False)
    for dk, ok in cov.items():                       # who covers whom: a thin orange tie
        a, b = p.players[dk], p.players[ok]
        (x0, y0), (x1, y1) = _P(f, p, a.d - 0.55, a.w), _P(f, p, b.d + 0.55, b.w)
        ax.plot([x0, x1], [y0, y1], color=style.DEFENSE, lw=1.6, zorder=7, solid_capstyle="round")
    for k in [k for k in ("LT", "LG", "C", "RG", "RT", "Y") if k not in cov.values()]:
        say(f, p, -1.85, p.players[k].w, "uncovered", color=GREEN, fontsize=7.2, weight="bold")
    ax.set_title(ttl, fontsize=9, loc="left", color=style.INK, fontweight="bold")
fig.tight_layout(h_pad=1.0)
plt.show()
Figure 15.6: The same two fronts, now from the offensive line’s point of view. An orange tie links each defensive lineman to the offensive lineman he is lined up on, who is covered. Linemen with nobody on them (green) are uncovered: the nearest defender in front of them is a linebacker. Top: the LG and the RT are uncovered. Bottom: both guards are uncovered, the center and both tackles covered; the 5 and the 4i bracket the left tackle, so he is covered twice over.

An offensive lineman is covered when a defensive lineman is lined up on him, head-up or on either shoulder. He is uncovered when nobody is, so that the nearest defender in front of him is a linebacker four or five yards away. In the top front of Figure 15.6, the 5 covers the left tackle, the 1 covers the center, the 3 covers the right guard and the 9 covers the tight end; the left guard and the right tackle are uncovered.

Why every blocking scheme starts here. A covered lineman has a man in his face at the snap and usually has to deal with him first. An uncovered lineman is the offense’s free resource. He can help a neighbor on a defensive lineman (a double team), or go straight to a linebacker at the second level, the linebackers’ depth. Which uncovered linemen exist, and where, shapes what any run play can do against that front.

Uncovered does not always mean free, though; you still have to count. Look at the bottom front. Both guards are uncovered, but they are not equally free. On the left, the 5 and the 4i bracket the left tackle, and one man cannot block two, so the left guard has to help with the 4i before he can think about a linebacker. On the right, the tackle has only the 4i, so the right guard can double-team the 4i with him and then climb: he is the natural climber. The center, covered by a 0, has the heaviest man on the field on his nose and little chance to help anyone. A defense that wants to stop a certain run chooses its front partly to change who is covered, and who has to stay home to help.

Covered and uncovered is a snapshot taken before the snap, and the defense knows it. Defensive linemen can slant at the snap, stepping sideways into the next gap instead of straight ahead (Defensive Line Play teaches it), and a lineman who was uncovered can suddenly have a man in his face. How a blocking scheme copes with that is one of the big differences between the two families at the end of this chapter.

One refinement, which you will meet in Zone Running: zone-blocking teams count “covered” only on the side the play is going. A defender shaded on a lineman’s backside shoulder is not his problem on a zone run, because he is stepping away from him. That rule is why the same lineman can be covered on a run to the right and uncovered on a run to the left.

The blocks: eight words for what a blocker does

Run blocking looks like a pile of large men shoving. It is actually a small number of distinct jobs, each with a name, each chosen for a reason. This chapter teaches eight. They are enough to describe nearly every NFL run you will see; a few specialty blocks arrive later, in the chapters that first need them (the cut block in 03-02, the log in 03-03, and the seal and crack on the perimeter in 03-05). What a blocker may legally do, such as where he may put his hands and when a block from behind or below the waist becomes illegal, is in Contact Rules and Penalties.

Show the Python
DD = 1.8   # defenders drawn a little deeper than real (about 1 yard) so each block's line shows
SPAN = 7.6


def plate_drive(p):
    p.block("RG", pts=[(1.55, 0.0)])
    go_to(p, "DL", (3.6, 1.6), "path", speed=1.5)


def plate_down(p):
    go_to(p, "RT", (1.2, 2.95), via=[(0.25, 3.25)])
    go_to(p, "DL", (2.6, 1.15), "path", speed=1.5)


def plate_reach(p):
    go_to(p, "RG", (1.15, 3.0), via=[(0.2, 2.15)])
    go_to(p, "RB", (3.8, 5.0), "run", via=[(-3.4, 2.6), (-0.6, 4.9)])


def plate_cutoff(p):
    go_to(p, "LT", (1.1, -1.75), via=[(-0.1, -2.75)])
    later.append([(DD, -1.75), (DD, -0.3)])


def plate_combo(p):
    go_to(p, "C", (1.0, 0.3))
    go_to(p, "RG", (1.0, 1.15))
    go_to(p, "RG", (3.75, 1.75), delay=0.2)
    later.append("oval")


def plate_pull(p):
    go_to(p, "LG", (3.6, 4.15), "pull", via=[(-1.6, -1.2), (-1.6, 4.3), (0.9, 4.45)])


def plate_kick(p):
    # drawn a beat after the snap: the tackle has already stepped down onto the 3 (panel 2)
    go_to(p, "RT", (0.95, 2.5))
    go_to(p, "FB", (1.15, 3.95), via=[(-2.6, 2.3), (-0.8, 3.7)], speed=5.0)
    go_to(p, "DE", (2.6, 5.7), "path", speed=1.5)
    go_to(p, "RB", (4.6, 3.45), "run", via=[(-4.6, 0.9), (-2.6, 2.2), (-0.8, 3.1), (1.6, 3.35)])


def plate_lead(p):
    go_to(p, "FB", (3.75, 2.45), via=[(-1.6, 2.4)], speed=5.0)
    go_to(p, "RB", (2.4, 1.75), "run", via=[(-5.6, 0.9), (-2.4, 2.2)])


DL3 = D("DL", "DL", DD, T("3"), "3")
BACKS = [O("FB", "FB", -4.5, 0, "F"), O("RB", "RB", -6.8, 0, "R")]
# (title, note, players, actions, left edge of the 7.6-yard-wide window)
PLATES = [
    ("1. Drive", "straight ahead:\nmove him off the ball", [D("DL", "DL", DD, T("2"), "2")], plate_drive, -2.2),
    ("2. Down", "block the man inside\nyou, from the side", [DL3], plate_down, -1.4),
    ("3. Reach", "get outside him and\nseal him inside", [DL3, O("RB", "RB", -6.0, 0, "R")], plate_reach, -1.6),
    ("4. Cut-off", "backside: get between\nhim and the play", [D("DL", "DL", DD, T("3", -1), "3")], plate_cutoff, -4.6),
    ("5. Combo", "two on one, then one\nclimbs to a linebacker",
     [D("DL", "DL", DD, T("1"), "1"), D("M", "LB", 4.6, 1.75, "M")], plate_combo, -2.2),
    ("6. Pull", "leave your spot, run\nbehind the line, lead up", [D("M", "LB", 4.6, 4.15, "M")], plate_pull, -2.45),
    ("7. Kick-out", "hit the end man from\ninside; push him out",
     [DL3, D("DE", "DL", DD, T("5") + 0.6, "5")] + BACKS, plate_kick, -1.4),
    ("8. Lead", "a back blocks ahead\nof the ball carrier", BACKS + [D("M", "LB", 4.6, 2.45, "M")], plate_lead, -2.2),
]
fig, axes = plt.subplots(2, 4, figsize=(6.6, 6.3))
for ax, (ttl, note, extra, build, w0) in zip(axes.flat, PLATES):
    later = []
    ol = [q for q in line("short") if w0 + 0.8 <= q.w <= w0 + SPAN - 0.8   # only whole markers
          and not (build is plate_reach and q.key == "RT")]                 # keep the reach path clear
    if build is plate_kick:                                                 # the tackle, already down on the 3
        ol = [q.moved(d=0.05, w=2.75) if q.key == "RT" else q for q in ol]
    p = Play(ol + extra, None, los=35, to_go=None)
    build(p)
    f = draw(p, ax=ax, lateral=(w0, w0 + SPAN), window=(-7.6, 5.6), title=False)
    for item in later:
        if item == "oval":
            pair_oval(f, p, 0.55, 0.75, 3.6, 3.7)
        else:
            dashed(f, p, item, color=style.DEFENSE, lw=1.2, dash=(0, (1.5, 1.5)))
    ax.set_title(ttl, fontsize=9, loc="left", color=style.INK, fontweight="bold")
    ax.text(1.0, 1.035, "play \u2192", transform=ax.transAxes, ha="right", va="bottom", fontsize=7,
            color=style.OFFENSE_DARK, fontweight="bold")
    ax.text(0.5, -0.02, note, transform=ax.transAxes, ha="center", va="top", fontsize=7, color=style.INK_2)
fig.subplots_adjust(left=0.01, right=0.99, top=0.95, bottom=0.07, wspace=0.08, hspace=0.32)
plt.show()
Figure 15.7: The eight core blocks, play going right in every panel. Defenders are drawn a little deeper than real (about a yard off the ball in a game) so each block’s path shows; orange arrows show where the defender is pushed or wants to go. 1, Drive (also called a base block): straight ahead, move the man back. 2, Down: block a man lined up inside you, from the side. 3, Reach: get outside a man on your play-side shoulder and seal him in (the tackle is left out so the guard’s path shows). 4, Cut-off: on the backside, step play-side and get between the defender and the play; the play is going away, so he only has to be slowed. 5, Combo: two linemen on one defender, then one climbs to the linebacker. 6, Pull: leave your spot, run flat behind the line, and turn up to block somebody where the play is going. 7, Kick-out (drawn a beat after the snap, with the tackle already blocking down on the 3): the fullback hits the end man (drawn a little wide) from the inside and pushes him toward the sideline; the run goes inside him. 8, Lead: a back runs through the hole ahead of the ball carrier and blocks the first defender who shows.

Work through Figure 15.7 one panel at a time.

1. Drive. The drive block is the simplest block in football: the defender is lined up on you, and you block him straight ahead and try to move him backward, off the ball. NFL coaches and broadcasters often call it a base block. Every other block is a variation on it. Why it exists: moving a defensive lineman a yard or two backward collapses the space linebackers need to get to the hole. What it costs: it is a pure strength contest. Drive-blocking a 320-pound defensive tackle alone, head-on, is the hardest way to move him, and against a better player it simply fails.

2. Down. On a down block the blocker goes after a defender lined up inside him, toward the center, and hits him from the side. Why it exists: angles. A defender is built to take on force from the front; shove him from the side and he has much less to push back with, the way a parked car is easy to rock sideways and hard to push forward. A down block also seals: it pins the defender inside, building a wall on the inside edge of the hole. Gap-scheme runs are built out of down blocks. What it costs: the down-blocker leaves the man on his outside unblocked, so somebody else (a puller, a fullback) has to deal with that man.

3. Reach. A reach block is the opposite problem: the defender is on your play-side shoulder, a step closer to the play than you, and you have to get your head and body outside him so he cannot get to the ball, sealing him inside. Why it exists: runs to the outside need the defenders inside them to be kept inside. What it costs: it is the hardest block in football. The defender is already a step ahead and moving the way you want to go; he only has to take one step sideways to stay outside you. That is why the reach is usually done with help (the zone chapter shows the two-man version). And it has to last: the runner is coming toward this defender, so the seal must hold until the ball carrier is past him.

4. Cut-off. The cut-off block is a backside block. The blocker steps toward the play and gets his body between a defender and the ball carrier, usually a defender on his play-side shoulder, the one who could chase the play. Why it exists: backside defenders do not need to be moved, only kept from pursuing, and a body in their path for one second is enough. What it costs: little, which is the point; but if the defender beats it, he is the man who tackles a cutback runner from behind. When two or more backside linemen do it together, each stepping play-side and taking whoever shows up, coaches call it a scoop.5 (Do not confuse the cut-off with the cut block, a low block at the thighs, which is a different thing taught in 03-02.)

Three of these blocks are easy to mix up, because the footwork can look alike. The difference is the side of the play and the job:

  • A down block is on the play side. The man is inside you, and you hit him from the side and drive him inward, because he is the inside wall of the hole and the runner is coming right past him.
  • A reach block is also on the play side, but the man is on your play-side shoulder, so you must get around him and seal him in. The runner is coming toward him, so the seal must hold until the runner is past: that is why it is the hard one.
  • A cut-off block is on the backside. The play is running away from this defender, so you do not have to move him or seal him for long; you only have to get your body into his path toward the ball. On the backside, the direction of the play is toward the center, so the man you cut off is often inside you, exactly where a down block’s man would be (panel 4 shows one). Same spot, different job: the down-blocker drives his man; the cut-off blocker just gets in the way, and a moment’s delay is enough because the ball is going the other way.

5. Combo. A combo block, also called a double team, puts two adjacent linemen on one defensive lineman: usually one covered and one uncovered. They drive him together, and both keep their eyes on the linebacker behind him. Many playbooks name the pair: an ace is the center and a guard, usually on a 1, 2i or 2-technique, and a deuce is a guard and tackle on a 3-technique (the names vary by team).6 When the linebacker commits to a gap, one of the two comes off and climbs to the second level to block him; the other finishes the defensive lineman alone. Why it exists: it is the only way to get both things the run needs from one pair. Two men can move a defensive tackle off the ball when one man cannot, and the climb means the linebacker is still blocked. What it costs: timing. Come off too early and the defensive lineman splits the two; too late and the linebacker is already in the hole. The animation below shows it.

6. Pull. To pull is to leave your spot at the snap, step back off the line, and run sideways behind it to block somewhere else. It is mostly guards (and some centers and tackles) who pull. Why it exists: it adds a blocker where the play is going. A lineman lined up on the backside, where his block matters least, becomes an extra body at the point of attack, where it matters most. What it costs: the spot he left is now empty, so his neighbors must cover for it; pulling takes time, so a fast defender can beat the puller to the hole; and it is a tell. Linebackers are taught to read the guards, and a pulling guard tells them where the play is going. (Linebackers and the Second Level covers that read.)

7. Kick-out. A kick-out block hits the defense’s end man (short for the end man on the line of scrimmage, the last defender on the line on the play side) from the inside, and pushes him toward the sideline. The run then goes inside him. Why it exists: after the play-side linemen block down, the end man is the one defender left at the edge of the hole, and he is lined up outside everybody. Nobody on the line can reach him, so a blocker coming from the inside, a pulling guard or a fullback with a running start, takes him on with the angle in his favor. What it costs: an extra blocker, who has to come from somewhere (the backfield, or the backside of the line).

8. Lead. A lead block is thrown by a back, usually a fullback, who runs through the hole ahead of the ball carrier and blocks the first defender to show up, often a linebacker. Why it exists: the linemen can block the linemen, but somebody has to block the linebacker who is reading the play and running to the hole; the lead blocker arrives there at full speed, with the ball carrier right behind him. What it costs: a player who could otherwise run a route or carry the ball, which is one reason fullbacks became rare in the NFL. (The classic lead play, iso, is in 03-03.)

Notice a pattern in that list. Four blocks are about winning a matchup (drive, down, reach, cut-off): one blocker against one defender, with the block chosen to give the blocker the best angle. The other four are about changing the numbers (combo, pull, kick-out, lead): getting two blockers onto one defender, or getting a blocker to a spot where the defense did not expect one. That second group is where most run plays are won, and it is the subject of the rest of the chapter.

ImportantWhy it exists

Every block has a geometry. A defender is hard to move from the front and easy to move from the side, so offenses design runs so that as many blocks as possible are angle blocks (down blocks, kick-outs) rather than head-on drive blocks, and so that the hardest block, the reach, is done with help. When you watch a run and wonder why a lineman went sideways at the snap instead of straight ahead, the answer is almost always the angle.

The combo block, frame by frame

The combo is the block that confuses viewers most, because it changes halfway through. One moment two linemen are pushing the same man; a second later one of them is fifteen feet away on a linebacker. Here it is in slow motion. The animation (a numbered frame strip in the PDF) is a simulated play, drawn in the same coordinates as the NFL’s tracking data, not a real snap.

Show the Python
def combo_play():
    """An inside run right: C and RG double the 1-technique; RG climbs to the Mike when he commits."""
    off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("RB", "RB", -5.5, 0, "R")]
    dfn = front([("LE", "5", -1), ("L3", "3", -1), ("N1", "1", 1), ("RE", "5", 1)],
                lbs=[("WILL", 4.6, -2.6, "W"), ("MIKE", 4.6, 1.0, "M"), ("SAM", 4.2, 6.6, "S")])
    p = Play(off, dfn, los=35, to_go=None)
    # the double team: both linemen into the 1, drive him back, then the RG comes off to the Mike
    go_to(p, "C", (-0.05, 0.3), speed=2.4)
    go_to(p, "RG", (-0.05, 1.3), speed=2.0, via=[(-0.4, 1.45)])
    go_to(p, "N1", (1.3, 0.75), "path", speed=0.8)                       # held up at the line ...
    go_to(p, "N1", (1.8, -0.7), "path", speed=1.3, delay=0.1)            # ... then driven back and turned
    go_to(p, "C", (0.55, -0.95), speed=1.3, delay=0.1)                   # the center finishes him alone
    go_to(p, "MIKE", (3.5, 1.6), "path", speed=3.2, delay=0.15)          # reads run, steps up into a gap
    go_to(p, "MIKE", (3.8, 2.45), "path", speed=1.4)
    go_to(p, "RG", (0.4, 1.6), speed=1.6)                                # still on the 1 ...
    go_to(p, "RG", (2.35, 2.05), speed=3.4)                               # ... then climbs when the Mike commits
    # everyone else, simply (engaged pairs kept a marker apart)
    go_to(p, "LG", (-0.1, -2.15), speed=1.6); go_to(p, "L3", (1.25, -2.2), "path", speed=0.6)
    go_to(p, "LT", (-0.1, -3.5), speed=1.6, via=[(-0.5, -3.3)]); go_to(p, "LE", (1.3, -3.75), "path", speed=0.6)
    go_to(p, "RT", (-0.05, 3.75), speed=1.6); go_to(p, "RE", (1.35, 4.0), "path", speed=0.6)
    go_to(p, "Y", (3.3, 6.0), speed=3.0, via=[(0.6, 5.2)]); go_to(p, "SAM", (3.6, 6.2), "path", speed=1.0)
    go_to(p, "WILL", (3.6, -0.6), "path", speed=2.8, delay=0.35)
    go_to(p, "QB", (-2.6, -0.7), "path", speed=3.0)
    go_to(p, "RB", (4.0, 0.95), "run", speed=4.2, via=[(-3.6, 0.8), (-1.0, 0.95), (1.7, 0.95)])
    p.handoff("RB", t=0.6)
    return p


def mark_hole(fld, t):
    """A dashed outline of the hole, once it has opened."""
    if t >= 1.2:
        x, y = _P(fld, P_COMBO, 1.5, 0.9)
        fld.ax.add_patch(Ellipse((float(x), float(y)), 2.4, 1.9, fc="none", ec=GREEN, lw=1.4, ls=(0, (3, 2)),
                                 zorder=6.5))


P_COMBO = combo_play()
animation_or_strip(P_COMBO, [0.0, 0.45, 0.95, 1.6],
                   notes=["the 1 is on the C; Mike\nbehind him; RG uncovered", "C and RG both on the 1;\nboth watch the Mike",
                          "Mike steps up into a gap:\nRG comes off the 1", "RG on the Mike; C turns the\n1 alone; R in the hole"],
                   rings=(("RG", PURPLE), ("MIKE", style.DEFENSE)), lateral=(-3.8, 4.9), window=(-4.2, 5.8), ncols=2,
                   width_in=4.8, after=mark_hole, enter=("RB",))
Figure 15.8: A combo block on an inside run to the right (simulated, in Big Data Bowl tracking coordinates; faint lines are each player’s path so far). 1, the snap: the 1-technique is on the center, the Mike (orange ring) is stacked behind him, and the right guard (purple ring) has nobody on him, so the center and guard are the natural pair. 2: both linemen have their hands on the 1 and are driving him back, and both are watching the Mike. 3: the Mike reads run and steps up into a gap; that commitment is the guard’s signal to come off the double team and climb. 4: the guard is on the Mike, the center has turned the 1 by himself, and the running back is in the hole the pair created (dashed). The Will, coming over the top, is the free hat in this seven-man box: the next section is about him.

Four things to notice in Figure 15.8. First, why this pair: at the snap the 1 is on the center and nobody is on the right guard, so the uncovered guard is the free man who can help. Second, the 1-technique is moved backward, a yard or more, which one blocker alone could rarely do. Third, the guard does not leave until the Mike commits; he blocks the defensive lineman and reads the linebacker at the same time. Fourth, the hole appears in the space the double team cleared. The double team creates the movement and the climb keeps the linebacker out of the hole it made, and you will see that on nearly every inside run.

Which lineman climbs depends on the front. Against a 1 or a 2i, the center and a guard double him, as in the strip. When a four-man front puts both defensive tackles in 3-techniques (a common nickel look), the double teams are guard and tackle on each 3, and nobody covers the center at all: he is the free hat, and he climbs straight to a linebacker, or helps a guard if a tackle slants into the A gap. Either way, the modern center is often the man in space, which is why centers who can move are so valuable. The film room on Jason Kelce, later in the chapter, shows the best of them.

Hat math: counting blockers and defenders

Now the arithmetic. Coaches call it hat math (sometimes “counting hats,” a hat being a helmet, so a player): count the blockers, count the defenders, and see who is left over. The phrase you will hear most is “a hat on a hat”: every defender who can get to the run has a blocker assigned to him. If the defense has one more man than the offense has blockers, one defender is unblocked, and on a run that defender is usually the one who makes the tackle.

The count happens in the box, the area near the ball where the run is defended: from just outside one end of the offensive line to just outside the other (including an attached tight end), and about five to seven yards deep. You learned to count it in A First Look at Defense, along with light and loaded boxes, and Figure 15.9 is the same picture you saw there. What is new is that the blocks are now drawn, so you can see exactly who blocks whom and who is left over.

Show the Python
def eleven(slot=True):
    off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("RB", "RB", -7.0, 0, "R"),
                          O("H", "WR", -1.5, -9.0, "H"), O("X", "WR", -0.7, -15.0, "X"), O("Z", "WR", -1.5, 15.0, "Z")]
    return off


def box_defense(seven):
    dfn = front([("LE", "5", -1), ("L1", "1", -1), ("R3", "3", 1), ("RE", "9", 1)],
                lbs=[("WILL", 4.6, -2.2, "W"), ("MIKE", 4.6, 1.9, "M")])
    dfn += [D("NB", "NB", 5.0, -8.3, "$"), D("LCB", "CB", 7.0, -15.0, "CB"), D("RCB", "CB", 7.0, 15.0, "CB")]
    if seven:
        dfn += [D("SS", "S", 6.5, 6.6, "SS"), D("FS", "S", 13.0, 0.0, "FS")]
    else:
        dfn += [D("SS", "S", 12.5, 8.0, "SS"), D("FS", "S", 12.5, -8.0, "FS")]
    return dfn


def hat_blocks(p):
    """Six blockers, six defenders: who blocks whom."""
    go_to(p, "LT", (0.3, -3.75))                                   # the 5
    go_to(p, "C", (0.35, -0.55), via=[(-0.3, -0.3)])               # the 1, who is on him
    go_to(p, "LG", (3.7, -2.05), via=[(0.3, -1.75)])               # uncovered: climbs to the Will
    go_to(p, "RG", (0.3, 2.2))                                     # the 3
    go_to(p, "RT", (3.7, 2.1), via=[(0.4, 3.3), (2.4, 2.9)])       # uncovered: outside the 3, up to the Mike
    go_to(p, "Y", (0.3, 5.3))


fig, axes = plt.subplots(1, 2, figsize=(6.6, 4.4))
for ax, seven in zip(axes, (False, True)):
    p = Play(eleven(), box_defense(seven), los=35, to_go=None)
    hat_blocks(p)
    if seven:
        p.highlight("SS", color=style.DEFENSE)
    f = draw(p, ax=ax, lateral=(-10.5, 10.5), window=(-8.5, 15.0), title=False)
    shade_box(f, p, -4.6, 6.4, d1=7.6)
    n = 7 if seven else 6
    say(f, p, 9.2, -6.6 if seven else 0.0, f"{n} in the box\nv 6 blockers", color=GREEN, fontsize=7.2, weight="bold")
    if seven:
        point_to(f, p, (9.4, 6.6), (6.5, 6.6), "unblocked", color=style.DEFENSE_DARK, fontsize=7)
    else:
        say(f, p, 13.4, 0.0, "the two free men are 12+ yards away", color=style.DEFENSE_DARK, fontsize=6.6)
    say(f, p, 2.2, -7.2, "\u2190 X and CB", fontsize=6.4)
    say(f, p, 2.2, 7.2, "Z and CB \u2192", fontsize=6.4)
    ax.set_title("Two deep: a hat on every hat" if not seven else "One deep: one man free in the box",
                 fontsize=8.8, loc="left", color=style.INK, fontweight="bold")
fig.tight_layout(w_pad=0.6)
plt.show()
Figure 15.9: Hat math against one offense: one running back, one tight end, three receivers (11 personnel: the slot receiver H is drawn, and X and Z are wide, off the picture), so six blockers in the box (five linemen and the tight end). The receivers take the nickel back ($) and both cornerbacks with them. Left: the defense keeps two safeties deep, leaving six in the box (shaded): six blockers, six defenders, a hat on every hat. Each covered lineman blocks the man on him and the two uncovered ones (the left guard and right tackle) climb to the linebackers. The two defenders nobody blocks or covers are the safeties, more than 12 yards away. Right: one safety walks down into the box, making seven; the blocking scheme still has only six blockers, so one defender (ringed) is unblocked, five or six yards from the ball.

Read the two pictures in Figure 15.9 as a negotiation.

  • Six against six (left). The offense has a blocker for every defender in the box. The run has a fair fight up front, and if it gets through the line, the next defenders are two safeties a dozen yards away. Offenses love to run against this look. It is common now, because defenses have leaned into two-deep safeties to stop the pass: NFL Next Gen Stats measured split-safety coverage on 42.0% of dropbacks in 2025, up from 32.9% in 2018.7
  • Seven against six (right). The defense has rolled a safety down. Now there is one more defender than blockers, and the unblocked man is in the box, not twelve yards away. Some defender will be unblocked whatever the blocking scheme does; the scheme only gets to choose which one. A good run play leaves the defender who is farthest from the play, or the one the ball carrier can most easily make miss.

Why doesn’t the defense just put everyone in the box? Because every man it adds there is a man taken out of pass coverage. In the right-hand picture there is now only one deep safety, and each receiver outside has a cornerback on him with less help over the top. That is the trade the box count measures. It is why quarterbacks count the box before the snap and switch from a run to a pass when the numbers are bad (the kill call in The Pre-Snap Phase), and why defenses try to disguise how many men will really be in the box at the snap. Defensive coaches have a name for having one more than the offense can block: being plus-one in the run game, which is the subject of 05-05.

The offense can add blockers, of course. Bring in a second tight end or a fullback and there are seven blockers. But every blocker you add is a receiver you took off the field, so the defense needs fewer men in coverage and can bring another one into the box. The defense can match each added blocker with an added defender, one for one, and keep its extra man. The next section explains why that extra man is almost always there.

Why a quarterback who only hands off leaves you a man short

Count everyone on the field, not just the box. Eleven offensive players, eleven defensive players. On a normal handoff:

  • The ball carrier does not block anyone; he is the man the defense is trying to tackle.
  • The quarterback hands the ball off and then, usually, does nothing that matters. Nobody has to cover him or tackle him. For the rest of the play he is a spectator.
  • The other nine players (five linemen, and four tight ends, backs and receivers) each block a defender or take one away by running a route that a defender has to cover. Even on a run, a cornerback has to cover his receiver at the snap, because he does not yet know it is a run; by the time he finds out, he is ten yards from the ball.

So nine offensive players occupy nine defenders, and two defenders are left free with nobody assigned to them. The defense gets to choose where those two free men stand. Put both deep (the two-high picture) and the run gets a fair fight in the box but runs into two safeties if it breaks through. Put one in the box (the one-high picture) and that man can tackle the runner near the line. Either way, the offense is playing ten men against eleven. The quarterback is the missing man.

Show the Python
fig, axes = plt.subplots(1, 2, figsize=(6.6, 4.0))
for ax, reads in zip(axes, (False, True)):
    off = line("full") + [te(+1), O("QB", "QB", -5.0, 0, "Q"), O("RB", "RB", -5.0, -1.5, "R")]
    dfn = front([("LE", "5", -1), ("L1", "1", -1), ("R3", "3", 1), ("RE", "9", 1)],
                lbs=[("WILL", 4.6, -2.2, "W"), ("MIKE", 4.6, 1.9, "M"), ("SS", 5.2, 4.2, "SS")])
    dfn += [D("FS", "S", 13.0, 0.0, "FS")]
    p = Play(off, dfn, los=35, to_go=None)
    if reads:
        go_to(p, "LT", (3.7, -2.4), via=[(-0.3, -2.9)])                   # QB reads the end: climb to the Will
    else:
        go_to(p, "LT", (0.4, -3.1), via=[(-0.2, -3.5)])                   # no read: somebody must block the end
    go_to(p, "LG", (0.3, -1.0))                                           # the 1
    go_to(p, "C", (3.7, 1.6), via=[(-0.3, 0.4)])                          # climb to the Mike
    go_to(p, "RG", (0.3, 2.2))                                            # the 3
    go_to(p, "RT", (4.3, 3.9), via=[(-0.3, 3.5)])                         # climb to the safety
    go_to(p, "Y", (0.3, 5.4))                                             # the 9
    go_to(p, "RB", (2.4, 2.4), "run", via=[(-4.4, 0.6), (-1.4, 2.2)])
    if reads:
        go_to(p, "LE", (-2.4, -1.8), "path", speed=4.0, via=[(-1.2, -3.4)])
        p.read("LE")
        p.highlight("LE", color=style.DEFENSE)
    else:
        go_to(p, "WILL", (2.7, 1.2), "path", speed=4.0)                  # the free man runs to the ball
        p.highlight("WILL", color=style.DEFENSE)
    f = draw(p, ax=ax, lateral=(-9.2, 9.2), window=(-7.8, 14.6), title=False)
    if reads:
        dashed(f, p, [(-4.3, 0.2), (-3.5, -1.3), (-3.0, -3.8), (-1.2, -6.0), (3.0, -6.6)], color=GREEN, lw=1.5)
        say(f, p, 6.0, -6.2, "end chases:\nQ keeps", color=GREEN, fontsize=6.8)
        say(f, p, -6.2, 3.4, "Q reads the end", color=GREEN, fontsize=6.8)
        ax.set_title("A running QB: the read 'blocks' him", fontsize=8.8, loc="left", color=style.INK,
                     fontweight="bold")
    else:
        point_to(f, p, (7.6, -5.4), (4.6, -2.2), "unblocked:\nthe Will", color=style.DEFENSE_DARK,
                 fontsize=6.8, shrink=8)
        say(f, p, -6.2, 3.4, "Q hands off, watches", fontsize=6.8)
        ax.set_title("QB hands off: one man free", fontsize=8.8, loc="left", color=style.INK, fontweight="bold")
    say(f, p, 13.0, 4.6, "deep safety:\nfree either way", color=style.DEFENSE_DARK, fontsize=6.6)
fig.tight_layout(w_pad=0.6)
plt.show()
Figure 15.10: The defender a handoff leaves free, from the shotgun against seven in the box. Left: the quarterback hands off and watches. Six blockers take six of the seven box defenders; the left tackle blocks the backside end so he cannot chase, which leaves the Will (ringed) unblocked, and he runs to the ball. Right: the quarterback reads the backside end instead (green dashes), so nobody blocks the end and the left tackle can climb to the Will. If the end chases the back, the quarterback keeps the ball and runs where the end just left; the end has been ‘blocked’ without being touched, and now every man in the box is accounted for. The end is the one to read because he is the defender farthest from where the run is going. The deep safety is free either way.

Now give the quarterback a job. If he is a real threat to run, a defender has to account for him, and that defender cannot also tackle the running back. The cleanest version is the read: the offense deliberately leaves one defender unblocked and the quarterback watches him after the snap. If that defender plays the running back, the quarterback keeps the ball; if he plays the quarterback, the quarterback hands off. Either way the read has done a blocker’s work: the defender is “blocked” by the decision. The offense is back to eleven against eleven, and one of the defense’s free men has disappeared. That is the core idea of the zone read and every other option play, which Option Football builds out properly. (Read option is the umbrella name you will hear for this family; the zone read is its most common play.) Jim Harbaugh, whose 49ers ran the read option with Colin Kaepernick, put it plainly in the week before Super Bowl XLVII, crediting the thought to Lou Holtz: without an option attack “the offense is basically playing with 10,” but when the quarterback is a threat to run, “that gets the numbers back to even, back to 11-on-11.”8

That arithmetic is why running quarterbacks change a run game: the 2019 Ravens, an option-heavy offense built around Lamar Jackson, set the NFL record for team rushing yards (3,296), and he did not have to keep the ball every time to do it.9

There is a quieter version of the same idea that every offense uses: the pass threat. Each receiver who might run a route takes a defender with him, which is why defenses facing three or four receivers keep fewer men in the box. A quarterback who can make the defense pay for loading the box with an accurate throw is, in run-game arithmetic, worth a blocker too. And when the quarterback runs the ball himself on a designed run (a sneak, or the QB power of 03-04, a planned quarterback run behind a pulling lineman and a lead blocker), the ball carrier is the quarterback, so the running back becomes a blocker: the offense gains a hat. That is the arithmetic behind the tush push, too (Red Zone, Goal Line, and Short Yardage).

CautionCommon misconception

“Running quarterbacks are dangerous because they are fast.” Speed helps, but the bigger effect is arithmetic. A quarterback the defense has to account for on every run takes a defender away from the running back, even on the plays where he hands off. That is why an offense can get a better run game from a quarterback who keeps the ball only a few times a game: the threat does the work.

Two philosophies: zone and gap

Every running play in this book is built from the pieces above, and coaches assemble them in two great families. You will spend a chapter on each; here is the map.

Show the Python
def zg_defense():
    dfn = front([("LE", "9", -1), ("L1", "1", -1), ("R3", "3", 1), ("RE", "5", 1)],
                lbs=[("WILL", 4.6, -2.4, "W"), ("MIKE", 4.6, 1.8, "M")])
    return [q.moved(w=q.w + 0.7) if q.key == "RE" else q for q in dfn]      # a wide 5, for room


def zone_side(ax):
    off = line("full") + [te(-1), O("QB", "QB", -1.9, 0, "Q"), O("RB", "RB", -7.0, 0, "R")]
    p = Play(off, zg_defense(), los=35, to_go=None)
    go_to(p, "RT", (0.3, 4.15), via=[(-0.5, 3.65)])                  # covered: steps right, takes the 5
    go_to(p, "RG", (0.3, 2.0), via=[(-0.5, 2.0)])                    # covered: the 3
    go_to(p, "LG", (0.3, -0.45), via=[(-0.5, -1.05)])                # the 1 is in his play-side gap
    go_to(p, "C", (3.7, 1.25), via=[(-0.4, 0.55)])                   # uncovered to the play side: climbs
    go_to(p, "LT", (3.7, -1.95), via=[(-0.4, -2.6)])                 # uncovered: climbs to the Will
    go_to(p, "U", (0.25, -5.15), via=[(-0.5, -4.4)])                 # backside: cut-off on the end
    go_to(p, "RB", (-1.4, 2.4), "run", via=[(-4.4, 1.0)])
    p.highlight("RB")
    f = draw(p, ax=ax, lateral=(-8.0, 8.4), window=(-8.4, 7.0), title=False)
    for pts in ([(-1.4, 2.4), (2.8, 3.0)], [(-1.4, 2.4), (0.6, 0.55), (3.0, -0.5)],
                [(-1.4, 2.4), (-0.4, 5.55), (2.6, 6.3)]):
        dashed(f, p, pts, color=GREEN, lw=1.4)
    say(f, p, 5.5, 5.4, "the back\nreads the hole", color=GREEN, fontsize=6.8)
    say(f, p, -3.3, -4.8, "everyone steps\nthe same way", color=style.OFFENSE_DARK, fontsize=6.8)
    ax.set_title("Zone: block an area", fontsize=9, loc="left", color=style.INK, fontweight="bold")


def gap_side(ax):
    off = line("full") + [te(-1), O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.5, 0, "F"), O("RB", "RB", -7.0, 0, "R")]
    p = Play(off, zg_defense(), los=35, to_go=None)
    go_to(p, "RT", (0.35, 2.85), via=[(-0.3, 3.05)])                  # down on the 3 ...
    go_to(p, "RG", (3.7, -1.75), via=[(0.05, 2.0)])                   # ... with the RG, who climbs to the Will
    go_to(p, "C", (0.35, -0.4), via=[(-0.4, -0.15)])                  # back block on the 1
    go_to(p, "LT", (-1.1, -2.0), via=[(-0.9, -2.9)])                  # hinge: close the gap the puller left
    go_to(p, "U", (0.25, -5.15), via=[(-0.5, -4.4)])                  # cut off the end
    go_to(p, "LG", (3.6, 2.45), "pull", via=[(-2.75, -1.1), (-2.75, 3.15), (-1.4, 3.95), (0.7, 3.75)])
    go_to(p, "FB", (0.35, 4.3), via=[(-2.9, 3.1), (-1.1, 4.45)], speed=5.0)   # kick out the end
    go_to(p, "RE", (2.2, 6.2), "path", speed=1.5)
    go_to(p, "RB", (2.4, 3.3), "run", via=[(-4.6, 1.2), (-2.2, 3.0), (0.3, 3.35)])
    p.highlight("RB"); p.highlight("LG", color=PURPLE)
    f = draw(p, ax=ax, lateral=(-8.0, 8.4), window=(-8.4, 7.0), title=False)
    pair_oval(f, p, 0.25, 2.4, 3.3, 2.4)
    point_to(f, p, (5.5, 5.6), (1.3, 3.55), "fixed hole:\nthe C gap", color=GREEN, fontsize=6.8, shrink=3)
    say(f, p, -3.3, -4.8, "down blocks,\na puller, a kick-out", color=style.OFFENSE_DARK, fontsize=6.8)
    ax.set_title("Gap: block a man, add a blocker", fontsize=9, loc="left", color=style.INK, fontweight="bold")


fig, axes = plt.subplots(1, 2, figsize=(6.6, 4.2))
zone_side(axes[0]); gap_side(axes[1])
fig.tight_layout(w_pad=0.7)
plt.show()
Figure 15.11: The two blocking philosophies against the same four-man front (the end on the right drawn a little wide so the paths show), both aimed to the right. Left, zone: every lineman steps the same way and blocks whoever comes into his area. The covered right guard and right tackle take the men on them, the left guard takes the 1 (who is in his play-side gap), and the uncovered center and left tackle climb to the linebackers. The running back aims at the right guard’s outside hip and reads the blocks: three possible lanes (green dashes), decided after the snap. Right, gap (this play is called power): the right tackle and right guard double-team the 3 (green oval) until the guard climbs to the Will; the center blocks back on the 1, a down block toward the backside that fills the spot the puller left; the left guard (purple ring) pulls behind the line and leads up through the hole on the Mike; and the fullback kicks out the end. The hole is fixed in advance: the C gap, between the double team and the kick-out. In both panels the U cuts off the backside end, so every defender in the picture has a hat; the free men are the deep safeties, off the picture.

Zone blocking assigns blockers to areas. All the linemen step the same direction at the snap, each takes whoever enters his area, uncovered men double-team and climb, and the running back reads where the wall cracks. Its virtue is that it adapts: if the defense slants (the line movement from the covered-and-uncovered section) or blitzes, whoever arrives in a blocker’s area gets blocked. Its price is that blocks are rarely knock-down blocks, and the hole is not known in advance, so the play depends on a runner who can see it. (Zone Running is the full story.)

Gap blocking (also called man or power blocking) assigns blockers to men, chosen to give them angles, and moves extra blockers to a hole chosen in advance. Down blocks seal the inside, a kick-out walls off the outside, and a puller or a fullback leads through the space between them. Its virtue is numbers at the point of attack: it gets more blockers to the hole than the defense has defenders there. Its price is that it is easier to read (a pulling guard is a signpost) and more fragile against movement: each blocker was told which man to block, so if that man slants into the space a puller was supposed to run through, the play can die. (Gap Schemes covers power, counter, trap and their relatives.)

Neither is better. Almost every NFL team runs both, and good offenses build them to look alike for the first half-second so the defense cannot tell which is coming. The first thing to watch on any run is which family it belongs to, and you can usually tell from one question: does the whole line step the same way, or does somebody pull? The big exception is duo, a gap-family run with no puller that is built to look like inside zone (Gap Schemes); for that one, look for double teams driving straight at the linebackers rather than a line moving sideways together.

Where this language came from: the Hogs

Most of this vocabulary is older than anyone now coaching, but one team made it famous to a national audience, and its story explains why the blocks in this chapter are still the foundation.

When Joe Gibbs became Washington’s head coach in 1981, his offense was built to run behind a big offensive line. Line coach Joe Bugel started calling his linemen “the Hogs” in training camp in 1982 (“Okay, you hogs, let’s get running down there”), and the name stuck to a group of big, unglamorous blockers (center Jeff Bostic, guards Russ Grimm and Mark May, tackles Joe Jacoby and George Starke, among others) who became the most famous offensive line in football.10 Washington won three Super Bowls under Gibbs, after the 1982, 1987 and 1991 seasons, with three different starting quarterbacks, which tells you how much of the offense lived up front.

Gibbs’s teams are a good place to see the language in use because their signature runs were the gap-scheme plays this chapter just described: down blocks on the play side, guards and even tackles pulling around to kick out and lead, a fixed hole. Their counter play, with two backside linemen pulling (the left guard Russ Grimm and, unusually, the left tackle Joe Jacoby), became one of the most copied runs in football (it is taught in 03-03).11 And Gibbs’s answer to one defender, the Giants’ Lawrence Taylor, gave the run game a new blocker: Gibbs moved a back up near the line as an extra blocker for the edge, the position now called the H-back.12 That is hat math again. Taylor was a defender the existing blocking could not handle, so Gibbs added a hat.

NoteFilm room: Washington, Super Bowl XVII (1982 season)

The play: January 30, 1983, at the Rose Bowl. Washington trails Miami 17–13 with 10:10 left in the game and faces fourth-and-1 at the Miami 43. Gibbs calls “I-Right 70 Chip,” a short-yardage run to the left. (That is Washington’s own play name; its numbers do not follow the simple hole system earlier in the chapter, a reminder that numbering is a dialect.) Tight end Clint Didier goes in motion to the right and then reverses back to the left, and cornerback Don McNeal follows him. The play is designed, as the standard account of it puts it, to block everyone except the smallest defender on the field, the cornerback, and let John Riggins run through him. Behind Didier and fullback Otis Wonsley, Riggins breaks McNeal’s tackle at the line (McNeal had slipped as Didier changed direction) and outruns safety Glenn Blackwood for a 43-yard touchdown. Washington wins 27–17; Riggins carries 38 times for 166 yards and is named MVP.13

What to notice: this is hat math in its purest form. The offense could not block everybody, so it chose the defender to leave free: the smallest one, against a 230-pound back with a running start. The motion is what put him there. A cornerback who follows a man in motion across the formation is behaving like a man-coverage defender (the travel tell of Motion and Shifts), so when Didier came back to the left, McNeal came with him and ended up near the line on the play side, the one unblocked man between Riggins and the end zone. Watch the replay with the vocabulary: which side is the play side, which gap Riggins hits, and who leads (the fullback).

The modern echo of the Hogs is not one team but one position. As offenses spread out and defenses got faster, the center became the hub of the run game: the man who makes the line’s calls, who is usually uncovered and must climb, and who in some offenses pulls. Two recent lines show the vocabulary at its best.

NoteFilm room: Philadelphia Eagles 2022

The player: center Jason Kelce (#62), a sixth-round pick who weighed about 295 pounds, light for an NFL center, and who made six first-team All-Pro teams largely on the skills this chapter has been describing: coming off a double team to catch a linebacker in open space, and pulling around the edge faster than any center of his era.14 In 2022 the Eagles went 14–3 and reached Super Bowl LVII, which they lost 38–35 to Kansas City. By this book’s calculation from nflverse play-by-play, they led the league in EPA and in success rate on designed runs (planned runs, as opposed to quarterback scrambles), a count that includes Jalen Hurts’s designed runs and sneaks, a reminder that a quarterback who runs is part of the blocking arithmetic.15

The game: the divisional round against the Giants on January 21, 2023, a 38–7 win in which the Eagles ran for 268 yards.16

What to notice: watch Kelce on every run for a quarter. Count how often he is the lineman who comes off a double team and climbs to a linebacker, and how often he pulls or sprints out in front of a play to the edge. Then watch his guards: on most of the plays where Kelce climbs, a guard is finishing the defensive lineman Kelce left. That is the center-guard combo of Figure 15.8, done at a speed most centers cannot match.

NoteFilm room: Detroit Lions 2023–2024

The seasons: under offensive coordinator Ben Johnson, Detroit reached the NFC Championship Game after the 2023 season and went 15–2 in 2024. By the same nflverse calculation, the Lions were in the top five in EPA per designed run in both seasons and tied for the league lead in rushing touchdowns on designed runs both years.17 Their line was anchored by right tackle Penei Sewell (#58), a first-team All-Pro in 2023, 2024 and 2025, and center Frank Ragnow (#77), a second-team All-Pro in 2023 and 2024 who retired in June 2025 (a comeback attempt that November ended when he failed his physical).18 (Johnson became the Bears’ head coach in 2025, so this is a 2023–2024 offense, not Detroit’s current one.)

What to notice: pick a game and watch only the right side. Sewell’s blocks are a block-library tour: down blocks on runs to his side, drive blocks that move defensive ends a couple of yards off the ball, reach and cut-off blocks when the play goes away from him. Then watch Ragnow on the double teams in the middle: who climbs, and when. Name each block out loud as it happens.

Watch for it on Sunday

TipWatch for it

On Sunday: find the hole. For one quarter, on every run, do this.

Before the snap

  • Count the box and the blockers (five linemen, plus each tight end and fullback near the line). Six against six? Seven against six? Who would be the free man?
  • Read the defensive line in numbers, left to right (“5, 1, 3, 9”). Which guard has a 3-technique on him? Which linemen are uncovered?

The first half-second

  • Watch the running back’s first step. It usually points at the play side and at the point of attack. Say the gap out loud before he gets there: “right B gap.” The exception is a counter play, where the back’s first step is a deliberate lie, away from the play (03-03).
  • Glance at the guards. Does one pull? (Gap play, and the puller is running to the hole.) Does the whole line step together? (Zone, and the hole is not decided yet.) Double teams driving straight ahead with nobody pulling? Think duo.

After the play (on the replay)

  • Name the gap he actually hit. Same as your guess? On a gap play it usually is; on a zone play it often is not, and that is the play working, not failing.
  • Find one block of each kind you can see: a down block, a double team with a climb, a kick-out, a lead.
  • Find the unblocked defender. Where was he, and did he make the tackle?

For your prediction log: before each run write the gap you expect (say, “R-B”); afterwards write the gap he hit and Z (zone) or G (gap). After a quarter you will know whether this offense’s first step tells the truth.

Predict the play

TipPredict the play

Drill 1. Find the hole. First-and-10. Figure 63.9 shows the first half-second of a run: the linemen’s first steps, a pulling guard (purple ring), the fullback heading for the edge, and the running back’s first steps. The defense has a linebacker (S) standing up on the line outside the tight end. Where is the point of attack (name the gap)? Name the block the Y and the RT are throwing, and say what the fullback and the pulling guard are about to do.

Show the Python
off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.5, 0, "F"), O("RB", "RB", -7.0, 0, "R")]
dfn = front([("LE", "5", -1), ("L1", "1", -1), ("R3", "3", 1), ("R7", "7", 1)],
            lbs=[("WILL", 4.6, -2.4, "W"), ("MIKE", 4.6, 1.6, "M"), ("SAM", 1.0, 6.9, "S")])
p = Play(off, dfn, los=40, to_go=10, title="Drill 1: the first half-second. Where is it going?")
go_to(p, "Y", (0.3, 4.25), via=[(-0.3, 4.55)])                 # down on the 7
go_to(p, "RT", (0.4, 2.8), via=[(-0.3, 3.05)])                 # down on the 3 ...
go_to(p, "RG", (0.3, 2.0), via=[(-0.4, 1.75)])                 # ... with the RG (who will climb to the Will)
go_to(p, "C", (0.35, -0.45), via=[(-0.4, -0.2)])               # back on the 1
go_to(p, "LT", (-1.1, -2.0), via=[(-0.9, -2.9)])               # hinge
go_to(p, "LG", (-1.6, 5.7), "path", via=[(-2.75, -1.1), (-2.75, 4.6)])  # pulls (where to, you decide)
go_to(p, "FB", (-1.0, 6.4), "path", via=[(-3.2, 3.6)], speed=5.0)       # heading for the edge
go_to(p, "RB", (-4.4, 2.2), "run", via=[(-6.1, 0.75)])         # first steps
p.highlight("LG", color=PURPLE)
f = draw(p, width_in=5.6, lateral=(-8.6, 10.6), window=(-8.4, 7.0))
say(f, p, 3.4, 8.2, "S: standing\nup on the edge", color=style.DEFENSE_DARK, fontsize=6.8)
plt.show()
Figure 15.12: Drill 1: the first half-second of a run from the I-formation. The tight end and the right tackle have stepped inside, the right guard has stepped toward the 3-technique with the tackle, the center and left tackle have stepped to their left, the left guard (purple ring) is pulling to the right, the fullback is heading outside, and the running back’s first steps angle to the right.

The D gap, just outside where the tight end lined up. Everything on the play side is going inside: the Y is down-blocking the 7-technique and the RT is down-blocking the 3-technique, hitting each from the side and sealing the inside of the hole. (As the Y steps inside, the hole opens where he stood, so you may also hear it called the C gap; what matters is that it is outside the Y’s down block and inside the kick-out.) That leaves the end man, the S standing up outside the tight end, for the fullback to kick out: he will hit him from the inside and push him toward the sideline. The pulling left guard turns up into the space between the down blocks and the kick-out and leads through it onto the first linebacker who shows (here the Mike, flowing over). The running back follows the puller. Inside the hole: down blocks. Outside it: the kick-out. Through it: a lead. That combination is the play called power, the signature gap-scheme run, and 03-03 builds it fully.

The rest of the line is filling in behind the puller. The right guard helps the right tackle on the 3 (a double team) and then climbs to the backside linebacker, the Will, because the puller is taking the Mike. The center blocks back on the 1: a down block toward the backside that also fills the spot the left guard just left. The left tackle hinges: he steps inside to protect the gap the puller vacated, then turns out. That leaves one defender in the box unblocked: the backside 5-technique. He is the man the play chooses to leave free, because he is the farthest from the hole and has to chase the play from behind.

The tell you could have used: the back’s first steps aimed outside the tackle, and the guard pulled the same way. A zone run does not pull guards; a pulling guard almost always runs to the hole.

TipPredict the play

Drill 2. Count the hats. Second-and-2. The offense brings in a fullback and lines up in the I-formation with one tight end (21 personnel); the defense answers with four down linemen, three linebackers and two deep safeties. Do the hat math for a run. Who is unblocked? If the defense wants to stop the run harder, what will it do, and what does that give the offense?

Show the Python
off = line("full") + [te(+1), O("QB", "QB", -1.9, 0, "Q"), O("FB", "FB", -4.5, 0, "F"), O("RB", "RB", -7.0, 0, "R"),
                      O("X", "WR", -0.7, -11.0, "X"), O("Z", "WR", -1.5, 11.0, "Z")]    # tight splits
dfn = front([("LE", "5", -1), ("L1", "1", -1), ("R3", "3", 1), ("R7", "9", 1)],
            lbs=[("WILL", 4.6, -2.6, "W"), ("MIKE", 4.6, 1.2, "M"), ("SAM", 4.4, 6.4, "S")])
dfn += [D("LCB", "CB", 6.0, -11.0, "CB"), D("RCB", "CB", 6.0, 11.0, "CB"),
        D("FS", "S", 12.0, -6.5, "FS"), D("SS", "S", 12.0, 6.5, "SS")]
p = Play(off, dfn, los=40, to_go=2, title="Drill 2: 2nd and 2, 21 personnel, a base defense")
f = draw(p, width_in=5.8, lateral=(-13.0, 13.0), window=(-8.6, 14.2))
shade_box(f, p, -4.6, 7.4, d1=7.0)
say(f, p, 9.0, 0.0, "the box", color=GREEN, fontsize=7.2, weight="bold")
plt.show()
Figure 15.13: Drill 2: second-and-2 (yellow line two yards ahead). 21 personnel in the I-formation against a base defense with two deep safeties. The shaded area is the box.

Seven against seven: a hat on every hat. In the box are seven defenders: four linemen (a 5, a 1, a 3 and a 9) and three linebackers. The offense has seven blockers: five linemen, the tight end, and the fullback as a lead blocker. Every defender in the box can be blocked, and the two free defenders are the safeties, twelve yards deep. On second-and-2 that is a very good look to run into: the runner needs two yards, and nobody unblocked is within ten of him. That is also why you will rarely see it. On second-and-short against a fullback and a tight end, most defenses would bring a safety down before the snap.

If the defense wants the run more, it brings a safety down into the box: eight against seven, plus-one again. But that leaves one deep safety for two receivers and a tight end, and on second-and-2 the offense can afford a shot: play-action, with the fullback and tight end selling the run, against a single safety. This is the back-and-forth of hat math: the offense adds a blocker, the defense adds a defender, and whoever over-commits gets punished by the other half of the playbook.

TipPredict the play

Drill 3. Read the front. The defense’s linemen are drawn with question marks. Read their alignments as technique numbers, left to right; for each one, ask whose shoulder he is on. Then: which offensive linemen are covered and which are uncovered? If the offense runs an inside run to the right, where will its double teams most naturally form, and who will climb to the linebackers?

Show the Python
dfn = front([("LE", "5", -1), ("L3", "3", -1), ("R3", "3", 1), ("RE", "9", 1)],
            lbs=[("WILL", 4.6, -1.6, "W"), ("MIKE", 4.6, 1.6, "M")])
# the two inside men are drawn on the guards' outside shoulders, a little closer to the guards than scale,
# so a 3 cannot be mistaken for a 4i (which would sit on the tackle's inside shoulder)
dfn = [q.moved(label="?", w=q.w - 0.3 * np.sign(q.w) if q.key in ("L3", "R3") else q.w) if q.pos == "DL" else q
       for q in dfn]
p = Play(line("full") + [te(+1), O("QB", "QB", -5.0, 0, "Q"), O("RB", "RB", -5.0, -1.5, "R")], dfn, los=40,
         to_go=10, title="Drill 3: name the front, then find the double teams")
f = draw(p, width_in=5.4, lateral=(-8.0, 8.6), window=(-6.6, 8.6))
play_arrow(f, p, 6.2, -2.0, 3.0, "inside run to the right", fontsize=7)
plt.show()
Figure 15.14: Drill 3: shotgun, one tight end on the right. Four defensive linemen (marked ?) and two linebackers. The offense will run inside, to the right.

5, 3, 3, 9. From the left: a 5-technique on the left tackle’s outside shoulder, a 3-technique on the left guard’s outside shoulder, a 3-technique on the right guard’s outside shoulder, and a 9 outside the tight end. (Two 3-techniques is a common modern nickel look: both defensive tackles in the B gaps, ready to penetrate.)

Covered: LT (by the 5), LG (by the left 3), RG (by the right 3), Y (by the 9). Uncovered: the center and the right tackle.

Now count the hats: six blockers (five linemen and the Y) against six defenders (four linemen, two linebackers). On an inside run to the right, the natural pair is the right guard and right tackle on the right 3-technique: the RG is covered, the RT is uncovered beside him, so they double-team the 3 and one of them (usually the RT) climbs to the Mike. The center, with nobody on him and nobody in his play-side A gap, climbs straight to the Will. On the left, the LG takes the left 3 and the LT the 5. (By the zone rule from the covered-and-uncovered section, the left 3 is on the LG’s backside shoulder, so the LG and LT may work together on him and leave the backside end alone; 03-02 shows that version.) The Y has the 9 by himself, and on an inside run to the right he is the edge of the play.

Notice what the front did: by putting both tackles in 3-techniques, the defense left the center uncovered, so he is the free hat who goes straight to a linebacker, which is one reason NFL offenses prize centers who can move.

Back to the replay

Here is the analyst’s sentence from the start of the chapter: “They’ve got a 3-technique over the right guard, and they run right at him. The guard and tackle double-team him, one of them climbs to the Mike, the fullback kicks out the end, and the back hits the C gap untouched.” Every word now means something:

  • A 3-technique over the right guard: a defensive tackle on the guard’s outside shoulder, in the B gap. The guard is covered; the tackle beside him is not, so he is free to help.
  • Run right at him: the play side is right and the point of attack is next to the 3. He is standing near the hole, so the blocks will have to move him out of it.
  • Double-team him, one of them climbs to the Mike: a combo block (a deuce, guard and tackle). They move the 3 together until the Mike commits, then one comes off to block him.
  • The fullback kicks out the end: a kick-out on the end man, from the inside, pushing him toward the sideline.
  • The C gap: just outside the right tackle, between the double team and the kick-out.
  • Untouched: the hat math worked. Every defender who could reach the hole had a blocker, and the free men were somewhere the play was not.

Takeaways

  • Gaps and holes name the spaces. Gaps are lettered A, B, C, D outward from the center (the defense’s language; every gap needs a defender, and every blocker the offense attaches to its line adds one). Holes are the offense’s numbers, usually odd on one side and even on the other, and “24” means the 2-back through the 4 hole, though numbering is a dialect.
  • Technique numbers say where a defender stands: even numbers head-up (0 center, 2 guard, 4 tackle, 6 tight end), odd numbers on an outside shoulder (1, 3, 5, and 9 outside the tight end), “i” on an inside shoulder (2i, 4i), and 7 inside the tight end. A shaded defender usually owns the gap he is shaded into; the 3-technique, 4i and 5-technique have become names for positions.
  • Covered or uncovered is the first question every lineman asks. Covered linemen have a man; uncovered linemen are the free hats, the ones who double-team and climb, as long as the count says nobody needs their help.
  • Eight blocks describe almost every run. Four win a matchup with the best angle available (drive, down, reach, cut-off); four change the numbers (combo, pull, kick-out, lead). Play-side blocks make the hole; backside blocks stop pursuit.
  • Hat math decides runs before the snap. A handoff leaves the quarterback a spectator, so the offense plays ten against eleven and the defense has two free men to place, deep or in the box. A quarterback who can run, or a read that “blocks” a defender without touching him, gets one back.
  • Zone and gap are the two answers. Zone blocks areas and lets the runner find the hole; gap blocks men with angles and brings extra blockers to a hole chosen in advance. Watch the first step: together, or does someone pull? (Duo is the gap run that hides it.)

Connections

Builds on: The Twenty-Two (the positions, the nose tackle, the Mike, Will and Sam), The Pre-Snap Phase (counting the box and the kill call), Classic Formations (the I-formation and singleback sets in these diagrams) and A First Look at Defense (the box, one-high and two-high shells).

Sets up:

  • Zone Running: the zone family in full, including how zone teams count “covered” by play side, the two-man reach, and the cut block.
  • Gap Schemes: power, counter, duo, trap, iso and the draw, built from down blocks, pullers, kick-outs and lead blocks.
  • Option Football: the read that “blocks” a defender, and the quarterback as the extra hat.
  • Pass Protection: the same covered-and-uncovered counting, applied to rushers.
  • Defensive Line Play: technique numbers from the defense’s side, one-gap and two-gap play, and how defensive linemen fight each block in this chapter.
  • Run Fits and Box Math: the defense’s half of hat math.
  • Kickoffs and Returns: a return is a run play, and its blocks use this vocabulary.

See also (case study): The Eagles: Trenches and the Tush Push; for the running-quarterback arithmetic at its peak, The Ravens’ Lamar Jackson Run Game.

If you want to go deeper: Chris B. Brown’s The Art of Smart Football and The Essential Smart Football (the quarterback run game and the arithmetic of the box); Pro Football Focus’s “Defensive Line Techniques: The Prototypes” for the numbering with player examples; and any Washington game from the early 1980s, watched for nothing but who blocks down and who pulls.

NoteGo deeper

Hat math in the data, and why it is slippery. A First Look at Defense showed the cost of a crowded box: on first-and-10 in 2023–2025, runs into five or fewer defenders succeeded about 40% of the time and runs into eight or more about 31%. Hat math says the number that really matters is not the box count but the box count minus the blockers. Count it that way and, surprisingly, most of the cost disappears from the averages. On the same first-and-10 designed runs, success was 35% when the defense had fewer men in the box than the offense had blockers, 36% when the two were even, 33% when the defense was plus-one, and 35% when it was plus-two or more.19

That is not hat math failing on the field. It is both sides choosing. Defenses go plus-one when the formation and the offense’s tendencies say run and they expect to win the fit; offenses that see a bad count often check out of the run (the kill call) or call a run built to handle the free man, such as a read; and the personnel count treats every tight end as a blocker, even one split out wide. A simple average cannot separate the arithmetic from the decisions made around it. Run Fits and Box Math takes up the defense’s side of this with data, and Expected Points, EPA and Success Rate and Tendencies give you the tools to untangle it.

NoteGo deeper

From diagrams to real tracking data. The combo-block animation is a gridiron simulation written in NFL Big Data Bowl coordinates, so real tracking data drops into the same drawing code. The 2025 Big Data Bowl release (2022 season, weeks 1–9) includes every player’s position ten times a second, before and after the snap, and its plays.csv carries PFF’s run-concept labels, so you can find inside runs and watch a center and guard come off a double team for real. The data needs a free Kaggle login, so the code (in the web edition, under “Show the Python”) is not run when this book is built.

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

plays = pd.read_csv("data/bdb/plays.csv")
iz = plays[plays["pff_runConceptPrimary"].astype(str).str.upper().str.contains("INSIDE ZONE")]
g, pl = iz.iloc[0][["gameId", "playId"]]

trk = bdb.load_tracking("data/bdb/tracking_week_*.csv")
one = bdb.prepare(trk, plays, game_id=g, play_id=pl)
show_animation(one, times=[0.0, 0.45, 0.95, 1.6])   # the same moments as the simulated combo block

  1. Hole and back numbering vary by team. The even-right, odd-left convention and the “back digit + hole digit” call are described in many coaching primers, e.g. “Gap (American football),” Wikipedia (https://en.wikipedia.org/wiki/Gap_(American_football)), and the play-calling primer at https://s3.amazonaws.com/footballtutorials/concepts/playcalling.pdf (Football-Tutorials.com: “The QB is always ‘1’, and the FB is always ‘3’,” the tailback is 2, and in four-back sets 2 is the back left of the fullback and 4 the back right of him; holes “numbered odd on the left and even on the right”). That primer numbers the hole behind the center 0, a reminder that numbering is a dialect; the back numbers are one common scheme, not a standard.↩︎

  2. The head-up/shade logic and the variations at the tight end: “Gap (American football),” Wikipedia (7 and 9 “are not universal”): https://en.wikipedia.org/wiki/Gap_(American_football); Big Blue View, “Defensive line techniques, gaps explained” (May 24, 2023: 6 head-up on the tight end, 7 on his inside shoulder as “the only anomaly,” 9 outside him, 8 with two tight ends to one side): https://bigblueview.com/2023/5/24/23734677/defensive-line-techniques-gaps-explained-big-blue-view-glossary-of-terms; Scouting Academy, “ITP Glossary: 7 Technique” (the Bryant numbering “swaps the order of the 6 and 7”): https://scoutingacademy.com/itp-glossary-7-technique/; Pro Football Focus (Sam Monson, 2011), “Defensive Line Techniques: The Prototypes”: https://www.pff.com/news/defensive-line-techniques-the-prototypes.↩︎

  3. Splits vary by team, by lineman and by play. Jeff Lutz, “Teach the Basics of Offensive Line Play,” Gridiron Strategies (Lutz, an offensive line coach at Wisconsin-Eau Claire, advises starting the season “taking 2-foot splits on all plays”): https://gridironstrategies.com/article/teach-the-basics-of-offensive-line-play. The diagrams in this book space the linemen wider than that, so the markers have room.↩︎

  4. Gregg Rosenthal, “Wade Phillips brings quick-fix wizardry to Los Angeles Rams’ D,” NFL.com (2017): Bryant “credited Bum with creating the universally used numbering system which tells defensive linemen where to line up based on their assigned numbers, like the ‘1 technique’ or ‘5 technique,’” which replaced code words that “varied from team to team”: https://www.nfl.com/news/wade-phillips-brings-quick-fix-wizardry-to-los-angeles-rams-d-0ap3000000834089. Port Arthur News, “An ode to Bum” (Phillips “while at NHS” taught the numbered techniques to Bryant at Texas A&M): https://www.panews.com/?p=10285. Phillips coached Nederland High School 1951–56 and was on Bryant’s Texas A&M staff in 1957: https://en.wikipedia.org/wiki/Bum_Phillips. (NFL.com dates the A&M hire to 1958, but Bryant left A&M for Alabama after the 1957 season.)↩︎

  5. Triple Option Football, “Glossary of Triple Option Offense Blocking Terms” (January 20, 2015): scoop is “a backside scheme allowing for the cutback,” in which backside linemen “scoop the area from the hand in their stance to the hand of the next man towards the play”: https://tripleoptionfootball.com/2015/01/20/glossary-of-triple-option-offense-blocking-terms/.↩︎

  6. Same glossary: ace is the play-side guard and center “to secure the 1, 2i, or 2 technique”; deuce is the play-side tackle and guard “to secure the 3 technique.” Bill Best, “Create Gaping Holes for Your Run Game with These Gap Scheme Combos,” Glazier Clinics, uses the same two names: https://www.glazierclinics.com/football-coach-resources/create-gaping-holes-for-your-run-game-with-these-gap-scheme-combos.↩︎

  7. NFL Next Gen Stats: split-safety coverage on 32.9% of dropbacks in 2018 and 42.0% in 2025, the highest since tracking began: https://www.nfl.com/news/the-coverage-that-turned-the-seahawks-into-super-bowl-winners-and-is-taking-the-nfl-by-storm.↩︎

  8. Kareem Copeland, “Jim Harbaugh: Option allows 49ers to play 11-on-11,” NFL.com, January 31, 2013: https://www.nfl.com/news/jim-harbaugh-option-allows-49ers-to-play-11-on-11-0ap1000000133218. Chris B. Brown’s The Essential Smart Football (2012) and The Art of Smart Football (2015) develop the same arithmetic.↩︎

  9. “Ravens break single-season team rushing record,” NFL.com (Dec 2019; the season finished at 3,296 yards, breaking the 1978 Patriots’ 3,165; Jackson ran for 1,206): https://www.nfl.com/news/ravens-break-single-season-team-rushing-record-0ap3000001092761; Baltimore Ravens, “Ravens set all-time record for team rushing yards in a season”: https://www.baltimoreravens.com/news/ravens-set-all-time-record-for-team-rushing-yards-in-a-season; Jackson’s 1,206 yards: https://en.wikipedia.org/wiki/2019_Baltimore_Ravens_season.↩︎

  10. “The Hogs (American football),” Wikipedia (Bugel coined the name in 1982 training camp; original members; three Super Bowl titles): https://en.wikipedia.org/wiki/The_Hogs_(American_football). Russ Grimm is in the Pro Football Hall of Fame (class of 2010): https://www.profootballhof.com/players/russ-grimm/.↩︎

  11. Rick Gosselin, “State Your Case: Joe Jacoby” (2015; updated 2022): on the counter trey “the left guard and left tackle pull to the right,” and Gibbs: “You can pull guards. But how many people pull tackles? We pulled Joe. He could run.” https://rickgosselin.com/state-your-case-joe-jacoby/.↩︎

  12. “H-back,” Wikipedia (Gibbs’s one-back offense and the H-back as a response to Lawrence Taylor, with Gibbs’s own account): https://en.wikipedia.org/wiki/H-back. See also the Pro Football Hall of Fame on Taylor: https://www.profootballhof.com/news/2023/06/gold-jacket-spotlight-lawrence-taylor-created-havoc/ (Gibbs: “You get a back blocking Lawrence Taylor, you lose”). Gibbs’s own account, as cited by Wikipedia: Nick Charles, “Taylor made,” CNNSI.com, August 12, 1999 (“We had to try in some way have a special game plan just for Lawrence Taylor”).↩︎

  13. “Super Bowl XVII,” Wikipedia (fourth-and-1 at the Miami 43 with 10:10 left in the fourth quarter, trailing 17–13; “I-Right 70 Chip”; Didier’s motion and McNeal’s slip; the design to block everyone but the cornerback; the run to the left behind Didier and Otis Wonsley; Riggins 38 carries, 166 yards, MVP; Washington 27, Miami 17): https://en.wikipedia.org/wiki/Super_Bowl_XVII; Riggins listed at 6-2, 230 lb: https://www.profootballhof.com/players/john-riggins/; Pro Football Reference box score: https://www.pro-football-reference.com/boxscores/198301300mia.htm.↩︎

  14. Jason Kelce: sixth round (191st overall), 2011; six first-team All-Pro selections (2017–2019, 2021–2023); listed at 6-3, 295; retired March 4, 2024: https://en.wikipedia.org/wiki/Jason_Kelce; Pro Football Reference: https://www.pro-football-reference.com/players/K/KelcJa00.htm.↩︎

  15. This book’s calculation from nflverse play-by-play (load_pbp), 2022 regular season: plays with play_type == "run", excluding quarterback scrambles and kneels, so quarterback designed runs and sneaks are included. Philadelphia ranked 1st of 32 in EPA per play (+0.09) and success rate (51%) and had 30 touchdowns on these plays. Season record and Super Bowl LVII result: Pro Football Reference, https://www.pro-football-reference.com/teams/phi/2022.htm.↩︎

  16. This book’s count from nflverse play-by-play (game 2022_20_NYG_PHI: 44 rushes for 268 yards; final score 38–7); Pro Football Reference box score: https://www.pro-football-reference.com/boxscores/202301210phi.htm.↩︎

  17. Same calculation as the Eagles note, 2023 and 2024 regular seasons: Detroit ranked 5th in EPA per designed run both years and tied for the most designed-run touchdowns both years (27 in 2023, with San Francisco and Miami; 29 in 2024, with Philadelphia and Buffalo); 5th in success rate in 2024, 8th in 2023. Ben Johnson was Detroit’s offensive coordinator 2022–2024 and became Chicago’s head coach for 2025 (this book’s checked facts, planning/FACTS-current.md §9).↩︎

  18. Penei Sewell (first-team All-Pro 2023, 2024, 2025): https://en.wikipedia.org/wiki/Penei_Sewell. Frank Ragnow (second-team All-Pro 2020, 2023, 2024; retired June 2, 2025; announced a return on November 26, 2025, which ended three days later when he failed his physical with a hamstring strain): https://en.wikipedia.org/wiki/Frank_Ragnow. Sewell’s third straight first-team selection (2025 team, announced January 2026): https://www.foxsports.com/articles/nfl/2025-nfl-allpro-team-see-who-made-the-roster.↩︎

  19. This book’s calculation from nflverse play-by-play joined to participation data (box counts charted by FTN), 2023–2025 regular seasons, first-and-10, designed runs (no scrambles, kneels or quarterback sneaks), all personnel groups. Blockers = offensive linemen + tight ends + backs beyond the first, from the offense_personnel field. Success rates: 35% (box at least one fewer than blockers; 5,568 runs), 36% (even; 10,099), 33% (plus-one; 3,153), 35% (plus-two or more; 505). By raw box count the same runs succeeded 40%, 37%, 34% and 31% against 5 or fewer, 6, 7 and 8 or more, matching 02-05.↩︎