From 8eed2267ccb88c47c8398b6f64565d4daf52b904 Mon Sep 17 00:00:00 2001 From: Oliver-Marcus Eder Date: Fri, 28 Aug 2026 00:13:27 +0200 Subject: [PATCH 1/2] docs: replace deprecated duration_ms with per-action intensity in examples --- examples/3-man-weave.ocf.json | 309 +++++++++++++++++++++++++++---- examples/pick-and-roll.ocf.json | 178 +++++++++++++++--- examples/transition-3v2.ocf.json | 236 +++++++++++++++++++---- 3 files changed, 625 insertions(+), 98 deletions(-) diff --git a/examples/3-man-weave.ocf.json b/examples/3-man-weave.ocf.json index c5ec249..dd8af1c 100644 --- a/examples/3-man-weave.ocf.json +++ b/examples/3-man-weave.ocf.json @@ -1,90 +1,321 @@ { "$schema": "https://opencoachingformat.org/schema/v1.json", + "sport": "basketball", "meta": { "id": "a3c2e1d0-9b8f-4a7e-b6c5-1d2e3f4a5b6c", "title": "3-Man Weave", "description": "Classic 3-player weave from full court. Players pass and follow their pass, weaving across the court to finish at the basket.", "author": "OCF Examples", - "tags": ["passing", "transition", "full-court", "3-player", "beginner", "conditioning"], + "tags": [ + "passing", + "transition", + "full-court", + "3-player", + "beginner", + "conditioning" + ], "difficulty": "beginner", "created": "2025-02-27T10:00:00Z", "source_format": "open" }, - "court": { "ruleset": "fiba", "type": "full_court", "drill_focus": "offense" }, + "court": { + "ruleset": "fiba", + "type": "full_court", + "drill_focus": "offense" + }, "entities": [ - { "type": "offense", "nr": 1, "x": 0.0, "y": -14.0 }, - { "type": "offense", "nr": 2, "x": -5.0, "y": -14.0 }, - { "type": "offense", "nr": 3, "x": 5.0, "y": -14.0 } + { + "type": "offense", + "nr": 1, + "x": 0, + "y": -14 + }, + { + "type": "offense", + "nr": 2, + "x": -5, + "y": -14 + }, + { + "type": "offense", + "nr": 3, + "x": 5, + "y": -14 + } + ], + "balls": [ + { + "id": "ball_1", + "carried_by": "offense_1" + } ], - "balls": [ { "id": "ball_1", "carried_by": "offense_1" } ], "frames": [ { "id": "frame_1", "label": "Start", "description": "offense_1 passes to offense_2 and follows the pass, cutting behind offense_2.", - "duration_ms": 1500, "actions": [ - { "player": "offense_1", "type": "pass", "to_player": "offense_2", "ball_id": "ball_1", "variant": "chest" }, - { "player": "offense_1", "type": "cut", "moves": [ { "to": { "x": -3.0, "y": -11.0 } } ], "after": "offense_1.pass" } + { + "player": "offense_1", + "type": "pass", + "to_player": "offense_2", + "ball_id": "ball_1", + "variant": "chest", + "intensity": "normal" + }, + { + "player": "offense_1", + "type": "cut", + "intensity": "fast", + "moves": [ + { + "to": { + "x": -3, + "y": -11 + } + } + ], + "after": "offense_1.pass" + } ], "end_state": { - "offense_1": { "x": -3.0, "y": -11.0 }, - "offense_2": { "x": -5.0, "y": -14.0 }, - "offense_3": { "x": 5.0, "y": -14.0 }, - "balls": { "ball_1": { "carried_by": "offense_2" } } + "offense_1": { + "x": -3, + "y": -11 + }, + "offense_2": { + "x": -5, + "y": -14 + }, + "offense_3": { + "x": 5, + "y": -14 + }, + "balls": { + "ball_1": { + "carried_by": "offense_2" + } + } } }, { "id": "frame_2", "label": "First Exchange", "description": "offense_2 dribbles to the middle and passes to offense_3, then follows the pass.", - "duration_ms": 2000, "actions": [ - { "player": "offense_2", "type": "dribble", "ball_id": "ball_1", "moves": [ { "to": { "x": 0.0, "y": -8.0 } } ] }, - { "player": "offense_2", "type": "pass", "to_player": "offense_3", "ball_id": "ball_1", "variant": "chest", "after": "offense_2.dribble" }, - { "player": "offense_2", "type": "cut", "moves": [ { "to": { "x": 3.5, "y": -4.0 } } ], "after": "offense_2.pass" }, - { "player": "offense_1", "type": "move", "moves": [ { "to": { "x": -5.0, "y": -8.0 } } ] } + { + "player": "offense_2", + "type": "dribble", + "ball_id": "ball_1", + "intensity": "normal", + "moves": [ + { + "to": { + "x": 0, + "y": -8 + } + } + ] + }, + { + "player": "offense_2", + "type": "pass", + "to_player": "offense_3", + "ball_id": "ball_1", + "variant": "chest", + "intensity": "normal", + "after": "offense_2.dribble" + }, + { + "player": "offense_2", + "type": "cut", + "intensity": "fast", + "moves": [ + { + "to": { + "x": 3.5, + "y": -4 + } + } + ], + "after": "offense_2.pass" + }, + { + "player": "offense_1", + "type": "move", + "intensity": "normal", + "moves": [ + { + "to": { + "x": -5, + "y": -8 + } + } + ] + } ], "end_state": { - "offense_1": { "x": -5.0, "y": -8.0 }, - "offense_2": { "x": 3.5, "y": -4.0 }, - "offense_3": { "x": 5.0, "y": -8.0 }, - "balls": { "ball_1": { "carried_by": "offense_3" } } + "offense_1": { + "x": -5, + "y": -8 + }, + "offense_2": { + "x": 3.5, + "y": -4 + }, + "offense_3": { + "x": 5, + "y": -8 + }, + "balls": { + "ball_1": { + "carried_by": "offense_3" + } + } } }, { "id": "frame_3", "label": "Second Exchange", "description": "offense_3 dribbles toward the middle and passes to offense_1 cutting from the left, then follows.", - "duration_ms": 2000, "actions": [ - { "player": "offense_3", "type": "dribble", "ball_id": "ball_1", "moves": [ { "to": { "x": 0.0, "y": 0.0 } } ] }, - { "player": "offense_3", "type": "pass", "to_player": "offense_1", "ball_id": "ball_1", "variant": "chest", "after": "offense_3.dribble" }, - { "player": "offense_3", "type": "cut", "moves": [ { "to": { "x": -3.0, "y": 5.0 } } ], "after": "offense_3.pass" }, - { "player": "offense_1", "type": "move", "moves": [ { "to": { "x": -5.0, "y": 0.0 } } ] }, - { "player": "offense_2", "type": "move", "moves": [ { "to": { "x": 5.0, "y": 0.0 } } ] } + { + "player": "offense_3", + "type": "dribble", + "ball_id": "ball_1", + "intensity": "normal", + "moves": [ + { + "to": { + "x": 0, + "y": 0 + } + } + ] + }, + { + "player": "offense_3", + "type": "pass", + "to_player": "offense_1", + "ball_id": "ball_1", + "variant": "chest", + "intensity": "normal", + "after": "offense_3.dribble" + }, + { + "player": "offense_3", + "type": "cut", + "intensity": "fast", + "moves": [ + { + "to": { + "x": -3, + "y": 5 + } + } + ], + "after": "offense_3.pass" + }, + { + "player": "offense_1", + "type": "move", + "intensity": "normal", + "moves": [ + { + "to": { + "x": -5, + "y": 0 + } + } + ] + }, + { + "player": "offense_2", + "type": "move", + "intensity": "normal", + "moves": [ + { + "to": { + "x": 5, + "y": 0 + } + } + ] + } ], "end_state": { - "offense_1": { "x": -5.0, "y": 0.0 }, - "offense_2": { "x": 5.0, "y": 0.0 }, - "offense_3": { "x": -3.0, "y": 5.0 }, - "balls": { "ball_1": { "carried_by": "offense_1" } } + "offense_1": { + "x": -5, + "y": 0 + }, + "offense_2": { + "x": 5, + "y": 0 + }, + "offense_3": { + "x": -3, + "y": 5 + }, + "balls": { + "ball_1": { + "carried_by": "offense_1" + } + } } }, { "id": "frame_4", "label": "Finish", "description": "offense_1 attacks the basket for the layup. offense_2 fills the right wing as the kick-out option.", - "duration_ms": 2000, "actions": [ - { "player": "offense_1", "type": "dribble", "ball_id": "ball_1", "moves": [ { "variant": "speed", "to": { "named": "basket" } } ] }, - { "player": "offense_1", "type": "shoot", "ball_id": "ball_1", "variant": "layup", "result": "make", "after": "offense_1.dribble" }, - { "player": "offense_2", "type": "move", "moves": [ { "to": { "named": "right_wing" } } ] } + { + "player": "offense_1", + "type": "dribble", + "ball_id": "ball_1", + "intensity": "fast", + "moves": [ + { + "variant": "speed", + "to": { + "named": "basket" + } + } + ] + }, + { + "player": "offense_1", + "type": "shoot", + "ball_id": "ball_1", + "variant": "layup", + "result": "make", + "intensity": "normal", + "after": "offense_1.dribble" + }, + { + "player": "offense_2", + "type": "move", + "intensity": "normal", + "moves": [ + { + "to": { + "named": "right_wing" + } + } + ] + } ], "end_state": { - "offense_1": { "named": "basket" }, - "offense_2": { "named": "right_wing" }, - "balls": { "ball_1": { "dead": true } } + "offense_1": { + "named": "basket" + }, + "offense_2": { + "named": "right_wing" + }, + "balls": { + "ball_1": { + "dead": true + } + } } } ] diff --git a/examples/pick-and-roll.ocf.json b/examples/pick-and-roll.ocf.json index 20764ae..8a1993d 100644 --- a/examples/pick-and-roll.ocf.json +++ b/examples/pick-and-roll.ocf.json @@ -1,43 +1,97 @@ { "$schema": "https://opencoachingformat.org/schema/v1.json", + "sport": "basketball", "meta": { "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "title": "Basic Pick & Roll", "description": "Ball handler uses a ball screen at the top of the key. Screener rolls to the basket for the finish.", "author": "OCF Examples", - "tags": ["pick-and-roll", "offense", "half-court", "2-player", "beginner"], + "tags": [ + "pick-and-roll", + "offense", + "half-court", + "2-player", + "beginner" + ], "difficulty": "beginner", "created": "2025-02-27T10:00:00Z", "source_format": "open" }, - "court": { "ruleset": "fiba", "type": "half_court", "drill_focus": "offense" }, + "court": { + "ruleset": "fiba", + "type": "half_court", + "drill_focus": "offense" + }, "entities": [ - { "type": "offense", "nr": 1, "x": 0.0, "y": 5.68 }, - { "type": "offense", "nr": 4, "x": -2.45, "y": 8.20 }, - { "type": "defense", "nr": 1, "x": 0.5, "y": 5.20 }, - { "type": "defense", "nr": 4, "x": -2.80, "y": 7.80 } + { + "type": "offense", + "nr": 1, + "x": 0, + "y": 5.68 + }, + { + "type": "offense", + "nr": 4, + "x": -2.45, + "y": 8.2 + }, + { + "type": "defense", + "nr": 1, + "x": 0.5, + "y": 5.2 + }, + { + "type": "defense", + "nr": 4, + "x": -2.8, + "y": 7.8 + } + ], + "balls": [ + { + "id": "ball_1", + "carried_by": "offense_1" + } ], - "balls": [ { "id": "ball_1", "carried_by": "offense_1" } ], "frames": [ { "id": "frame_1", "label": "Step 1 — Screen", "description": "offense_4 moves up from the left elbow to set a ball screen for offense_1 at the top of the key.", - "duration_ms": 1500, "actions": [ - { "player": "offense_4", "type": "screen", "for_player": "offense_1", "on_player": "defense_1", "variant": "ball_screen", "at": { "x": -0.5, "y": 6.7 }, "physicality": "hard" } + { + "player": "offense_4", + "type": "screen", + "for_player": "offense_1", + "on_player": "defense_1", + "variant": "ball_screen", + "at": { + "x": -0.5, + "y": 6.7 + }, + "physicality": "hard" + } ], "end_state": { - "offense_1": { "named": "top_of_the_key" }, - "offense_4": { "x": -0.5, "y": 6.2 }, - "balls": { "ball_1": { "carried_by": "offense_1" } } + "offense_1": { + "named": "top_of_the_key" + }, + "offense_4": { + "x": -0.5, + "y": 6.2 + }, + "balls": { + "ball_1": { + "carried_by": "offense_1" + } + } } }, { "id": "frame_2", "label": "Step 2 — Attack", "description": "offense_1 uses the screen and dribbles hard left toward the elbow; offense_4 rolls to the right block.", - "duration_ms": 2000, "actions": [ { "player": "offense_1", @@ -45,36 +99,106 @@ "ball_id": "ball_1", "intensity": "normal", "moves": [ - { "variant": "hesitation" }, - { "variant": "speed", "to": { "named": "left_elbow" }, "around_player": "defense_1", "intensity": "explosive" } + { + "variant": "hesitation" + }, + { + "variant": "speed", + "to": { + "named": "left_elbow" + }, + "around_player": "defense_1", + "intensity": "explosive" + } ] }, - { "player": "offense_4", "type": "cut", "variant": "basket", "intensity": "fast", "moves": [ { "to": { "named": "right_block" } } ], "tags": ["roll"] } + { + "player": "offense_4", + "type": "cut", + "variant": "basket", + "intensity": "fast", + "moves": [ + { + "to": { + "named": "right_block" + } + } + ], + "tags": [ + "roll" + ] + } ], "end_state": { - "offense_1": { "named": "left_elbow" }, - "offense_4": { "named": "right_block" }, - "balls": { "ball_1": { "carried_by": "offense_1" } } + "offense_1": { + "named": "left_elbow" + }, + "offense_4": { + "named": "right_block" + }, + "balls": { + "ball_1": { + "carried_by": "offense_1" + } + } } }, { "id": "frame_3", "label": "Step 3 — Finish", "description": "offense_1 throws a bounce pass to the rolling offense_4, who finishes with a layup.", - "duration_ms": 1500, "actions": [ - { "player": "offense_1", "type": "pass", "to_player": "offense_4", "ball_id": "ball_1", "variant": "bounce", "intensity": "hard" }, - { "player": "offense_4", "type": "shoot", "ball_id": "ball_1", "variant": "layup", "result": "make", "on_catch": true, "intensity": "soft" } + { + "player": "offense_1", + "type": "pass", + "to_player": "offense_4", + "ball_id": "ball_1", + "variant": "bounce", + "intensity": "hard" + }, + { + "player": "offense_4", + "type": "shoot", + "ball_id": "ball_1", + "variant": "layup", + "result": "make", + "on_catch": true, + "intensity": "soft" + } ], "end_state": { - "offense_1": { "named": "left_elbow" }, - "offense_4": { "named": "right_block" }, - "balls": { "ball_1": { "dead": true } } + "offense_1": { + "named": "left_elbow" + }, + "offense_4": { + "named": "right_block" + }, + "balls": { + "ball_1": { + "dead": true + } + } } } ], "areas": [ - { "form": "rectangle", "color": "yellow", "opacity": 0.2, "x": 0.0, "y": 10.5, "width": 4.9, "height": 4.0, "rotation": 0 } + { + "form": "rectangle", + "color": "yellow", + "opacity": 0.2, + "x": 0, + "y": 10.5, + "width": 4.9, + "height": 4, + "rotation": 0 + } ], - "labels": [ { "text": "Roll!", "x": 3.2, "y": 9.5, "color": "black" } ] + "labels": [ + { + "text": "Roll!", + "x": 3.2, + "y": 9.5, + "color": "black" + } + ] } diff --git a/examples/transition-3v2.ocf.json b/examples/transition-3v2.ocf.json index 17c2ae1..56f21ec 100644 --- a/examples/transition-3v2.ocf.json +++ b/examples/transition-3v2.ocf.json @@ -1,57 +1,193 @@ { "$schema": "https://opencoachingformat.org/schema/v1.json", + "sport": "basketball", "meta": { "id": "c9d8e7f6-5a4b-3c2d-1e0f-9a8b7c6d5e4f", "title": "3v2 Transition", "description": "Three offensive players attack two defenders in transition and create a quality shot through ball movement and spacing.", "author": "OCF Examples", - "tags": ["transition", "3v2", "full-court", "offense", "intermediate"], + "tags": [ + "transition", + "3v2", + "full-court", + "offense", + "intermediate" + ], "difficulty": "intermediate", "created": "2025-02-27T10:00:00Z", "source_format": "open" }, - "court": { "ruleset": "fiba", "type": "full_court", "drill_focus": "transition" }, + "court": { + "ruleset": "fiba", + "type": "full_court", + "drill_focus": "transition" + }, "entities": [ - { "type": "offense", "nr": 1, "x": 0.0, "y": -12.0 }, - { "type": "offense", "nr": 2, "x": -4.0, "y": -10.0 }, - { "type": "offense", "nr": 3, "x": 4.0, "y": -10.0 }, - { "type": "defense", "nr": 1, "x": -2.0, "y": 2.0 }, - { "type": "defense", "nr": 2, "x": 2.0, "y": 2.0 } + { + "type": "offense", + "nr": 1, + "x": 0, + "y": -12 + }, + { + "type": "offense", + "nr": 2, + "x": -4, + "y": -10 + }, + { + "type": "offense", + "nr": 3, + "x": 4, + "y": -10 + }, + { + "type": "defense", + "nr": 1, + "x": -2, + "y": 2 + }, + { + "type": "defense", + "nr": 2, + "x": 2, + "y": 2 + } + ], + "balls": [ + { + "id": "ball_1", + "carried_by": "offense_1" + } ], - "balls": [ { "id": "ball_1", "carried_by": "offense_1" } ], "frames": [ { "id": "frame_1", "label": "Push", "description": "offense_1 pushes the ball up the middle; offense_2 and offense_3 fill the wings at full speed.", - "duration_ms": 2000, "actions": [ - { "player": "offense_1", "type": "dribble", "ball_id": "ball_1", "moves": [ { "variant": "speed", "to": { "x": 0.0, "y": 1.0 } } ] }, - { "player": "offense_2", "type": "move", "moves": [ { "to": { "named": "left_wing" } } ] }, - { "player": "offense_3", "type": "move", "moves": [ { "to": { "named": "right_wing" } } ] } + { + "player": "offense_1", + "type": "dribble", + "ball_id": "ball_1", + "intensity": "fast", + "moves": [ + { + "variant": "speed", + "to": { + "x": 0, + "y": 1 + } + } + ] + }, + { + "player": "offense_2", + "type": "move", + "intensity": "fast", + "moves": [ + { + "to": { + "named": "left_wing" + } + } + ] + }, + { + "player": "offense_3", + "type": "move", + "intensity": "fast", + "moves": [ + { + "to": { + "named": "right_wing" + } + } + ] + } ], "end_state": { - "offense_1": { "x": 0.0, "y": 1.0 }, - "offense_2": { "named": "left_wing" }, - "offense_3": { "named": "right_wing" }, - "balls": { "ball_1": { "carried_by": "offense_1" } } + "offense_1": { + "x": 0, + "y": 1 + }, + "offense_2": { + "named": "left_wing" + }, + "offense_3": { + "named": "right_wing" + }, + "balls": { + "ball_1": { + "carried_by": "offense_1" + } + } } }, { "id": "frame_2", "label": "Draw and Kick", "description": "offense_1 attacks defense_1 to commit the help, then kicks to offense_3 in the right corner for the shot.", - "duration_ms": 2000, "actions": [ - { "player": "offense_1", "type": "dribble", "ball_id": "ball_1", "moves": [ { "to": { "named": "left_elbow" }, "around_player": "defense_1" } ] }, - { "player": "offense_3", "type": "cut", "variant": "fade", "moves": [ { "to": { "named": "right_corner" } } ] }, - { "player": "offense_1", "type": "pass", "to_player": "offense_3", "ball_id": "ball_1", "variant": "overhead", "after": "offense_1.dribble" }, - { "player": "offense_3", "type": "shoot", "ball_id": "ball_1", "variant": "three", "on_catch": true } + { + "player": "offense_1", + "type": "dribble", + "ball_id": "ball_1", + "intensity": "fast", + "moves": [ + { + "to": { + "named": "left_elbow" + }, + "around_player": "defense_1" + } + ] + }, + { + "player": "offense_3", + "type": "cut", + "variant": "fade", + "intensity": "fast", + "moves": [ + { + "to": { + "named": "right_corner" + } + } + ] + }, + { + "player": "offense_1", + "type": "pass", + "to_player": "offense_3", + "ball_id": "ball_1", + "variant": "overhead", + "intensity": "hard", + "after": "offense_1.dribble" + }, + { + "player": "offense_3", + "type": "shoot", + "ball_id": "ball_1", + "variant": "three", + "on_catch": true, + "intensity": "normal" + } ], "end_state": { - "offense_1": { "named": "left_elbow" }, - "offense_3": { "named": "right_corner" }, - "balls": { "ball_1": { "at": { "named": "basket" } } } + "offense_1": { + "named": "left_elbow" + }, + "offense_3": { + "named": "right_corner" + }, + "balls": { + "ball_1": { + "at": { + "named": "basket" + } + } + } }, "branches": { "make": "frame_reset", @@ -62,18 +198,48 @@ "id": "frame_oreb", "label": "Offensive Rebound", "description": "On a miss, offense_2 crashes from the left wing for the offensive rebound and finishes.", - "duration_ms": 1500, "start_state": { - "offense_2": { "named": "left_wing" }, - "balls": { "ball_1": { "at": { "named": "basket" } } } + "offense_2": { + "named": "left_wing" + }, + "balls": { + "ball_1": { + "at": { + "named": "basket" + } + } + } }, "actions": [ - { "player": "offense_2", "type": "rebound", "ball_id": "ball_1", "variant": "offensive", "tags": ["put_back"], "physicality": "aggressive" }, - { "player": "offense_2", "type": "shoot", "ball_id": "ball_1", "variant": "layup", "result": "make", "after": "offense_2.rebound" } + { + "player": "offense_2", + "type": "rebound", + "ball_id": "ball_1", + "variant": "offensive", + "tags": [ + "put_back" + ], + "physicality": "aggressive" + }, + { + "player": "offense_2", + "type": "shoot", + "ball_id": "ball_1", + "variant": "layup", + "result": "make", + "intensity": "normal", + "after": "offense_2.rebound" + } ], "end_state": { - "offense_2": { "named": "basket" }, - "balls": { "ball_1": { "dead": true } } + "offense_2": { + "named": "basket" + }, + "balls": { + "ball_1": { + "dead": true + } + } } }, { @@ -81,7 +247,13 @@ "label": "Reset", "description": "On a make, the ball is dead and the rep ends.", "actions": [], - "end_state": { "balls": { "ball_1": { "dead": true } } } + "end_state": { + "balls": { + "ball_1": { + "dead": true + } + } + } } ] } From 0742979337618b16cf1de376de013919b36be7ca Mon Sep 17 00:00:00 2001 From: Oliver-Marcus Eder Date: Fri, 28 Aug 2026 00:15:47 +0200 Subject: [PATCH 2/2] docs: make examples v1.2.0-conformant (sport field + fix/track continuous-ball-screen) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add explicit sport: basketball to the four core examples (best practice for v1.2.0; sport becomes required in v2). quick-mode deliberately stays sport-less as a living demonstration that sport-less documents remain valid (back-compat). - continuous-ball-screen was an untracked file that never validated (its meta.id was not a UUID). Fixed the id, added sport + per-action intensity, and now track it — the whole examples set validates for the first time. Co-Authored-By: Claude Opus 4.8 --- examples/based-on-references.ocf.json | 70 ++++- examples/continuous-ball-screen.ocf.json | 318 +++++++++++++++++++++++ 2 files changed, 377 insertions(+), 11 deletions(-) create mode 100644 examples/continuous-ball-screen.ocf.json diff --git a/examples/based-on-references.ocf.json b/examples/based-on-references.ocf.json index f293cfa..94fb3dc 100644 --- a/examples/based-on-references.ocf.json +++ b/examples/based-on-references.ocf.json @@ -1,11 +1,15 @@ { "$schema": "https://opencoachingformat.org/schema/v1.json", + "sport": "basketball", "meta": { "id": "9f8b7c6d-5e4a-4b3c-2d1e-0f9a8b7c6d5e", "title": "4-Out-1-In Variant with Lineage", "description": "Starts from the 4 Out 1 In formation with a tighter big, recorded as a variant of an existing play.", "author": "OCF Examples", - "tags": ["example", "external-references"], + "tags": [ + "example", + "external-references" + ], "difficulty": "intermediate", "created": "2026-08-26T10:00:00Z", "source_format": "open", @@ -15,7 +19,12 @@ "source": "https://opencoachingformat.org/registry/formations/basketball-v1.json", "source_version": "1.0.0", "adjustments": [ - { "entity": "offense_5", "dx": -0.5, "dy": 0.0, "note": "tighter to the block for this play" } + { + "entity": "offense_5", + "dx": -0.5, + "dy": 0, + "note": "tighter to the block for this play" + } ] }, "based_on_play": { @@ -25,15 +34,49 @@ "relationship": "variant" } }, - "court": { "ruleset": "fiba", "type": "half_court", "drill_focus": "offense" }, + "court": { + "ruleset": "fiba", + "type": "half_court", + "drill_focus": "offense" + }, "entities": [ - { "type": "offense", "nr": 1, "x": 0.0, "y": 5.68 }, - { "type": "offense", "nr": 2, "x": -6.75, "y": 8.6 }, - { "type": "offense", "nr": 3, "x": 6.75, "y": 8.6 }, - { "type": "offense", "nr": 4, "x": -7.5, "y": 13.98 }, - { "type": "offense", "nr": 5, "x": -0.5, "y": 10.5 } + { + "type": "offense", + "nr": 1, + "x": 0, + "y": 5.68 + }, + { + "type": "offense", + "nr": 2, + "x": -6.75, + "y": 8.6 + }, + { + "type": "offense", + "nr": 3, + "x": 6.75, + "y": 8.6 + }, + { + "type": "offense", + "nr": 4, + "x": -7.5, + "y": 13.98 + }, + { + "type": "offense", + "nr": 5, + "x": -0.5, + "y": 10.5 + } + ], + "balls": [ + { + "id": "ball_1", + "carried_by": "offense_1" + } ], - "balls": [ { "id": "ball_1", "carried_by": "offense_1" } ], "frames": [ { "id": "frame_1", @@ -41,8 +84,13 @@ "description": "Players hold the adjusted 4 Out 1 In shape.", "actions": [], "end_state": { - "offense_1": { "named": "top_of_the_key" }, - "offense_5": { "x": -0.5, "y": 10.5 } + "offense_1": { + "named": "top_of_the_key" + }, + "offense_5": { + "x": -0.5, + "y": 10.5 + } } } ] diff --git a/examples/continuous-ball-screen.ocf.json b/examples/continuous-ball-screen.ocf.json new file mode 100644 index 0000000..3ba368d --- /dev/null +++ b/examples/continuous-ball-screen.ocf.json @@ -0,0 +1,318 @@ +{ + "$schema": "https://opencoachingformat.org/schema/v1.json", + "sport": "basketball", + "meta": { + "id": "7f3e2a1b-9c4d-4e6f-8a2b-1d3c5e7f9a0b", + "title": "Continuous Ball Screen Set", + "description": "Multi-frame offensive set with consecutive ball screens. PG passes to wing and cuts, center screens and rolls, with options to kick out or reset.", + "author": "OCF Examples", + "tags": [ + "offense", + "half-court", + "ball-screen", + "continuous", + "pick-and-roll" + ], + "difficulty": "advanced" + }, + "court": { + "ruleset": "fiba", + "type": "half_court" + }, + "entities": [ + { + "type": "offense", + "nr": 1, + "x": 0, + "y": 7 + }, + { + "type": "offense", + "nr": 2, + "x": 6.75, + "y": 8.6 + }, + { + "type": "offense", + "nr": 3, + "x": -6.75, + "y": 8.6 + }, + { + "type": "offense", + "nr": 4, + "x": -2.45, + "y": 11 + }, + { + "type": "offense", + "nr": 5, + "x": 2.45, + "y": 11 + } + ], + "balls": [ + { + "id": "ball_1", + "carried_by": "offense_1" + } + ], + "frames": [ + { + "id": "frame_1", + "label": "Pass to Wing & Cut", + "description": "PG (1) passes to SG (2) on right wing, then cuts through to strong corner.", + "actions": [ + { + "player": "offense_1", + "type": "pass", + "to_player": "offense_2", + "variant": "chest", + "intensity": "normal" + }, + { + "player": "offense_1", + "type": "cut", + "moves": [ + { + "to": { + "named": "right_corner" + } + } + ], + "intensity": "fast" + } + ], + "end_state": { + "offense_1": { + "named": "right_corner" + }, + "balls": { + "ball_1": { + "carried_by": "offense_2" + } + } + } + }, + { + "id": "frame_2", + "label": "Center Ball Screen & Roll", + "description": "C (5) sets inside ball screen for SG (2). SG penetrates into paint, C rolls to baseline. PG lifts from corner to wing.", + "actions": [ + { + "player": "offense_5", + "type": "screen", + "for_player": "offense_2", + "variant": "ball_screen", + "at": { + "x": 3, + "y": 9.5 + }, + "physicality": "aggressive" + }, + { + "player": "offense_2", + "type": "dribble", + "moves": [ + { + "to": { + "x": 2, + "y": 11.5 + } + } + ], + "intensity": "normal" + }, + { + "player": "offense_5", + "type": "cut", + "moves": [ + { + "to": { + "named": "right_block" + } + } + ], + "tags": [ + "roll" + ], + "intensity": "fast" + }, + { + "player": "offense_1", + "type": "move", + "moves": [ + { + "to": { + "named": "right_wing" + } + } + ], + "intensity": "normal" + } + ], + "end_state": { + "offense_1": { + "named": "right_wing" + }, + "offense_2": { + "x": 2, + "y": 11.5 + }, + "offense_5": { + "named": "right_block" + }, + "balls": { + "ball_1": { + "carried_by": "offense_2" + } + } + } + }, + { + "id": "frame_3", + "label": "Kick to Left Wing", + "description": "If no shot, SG (2) passes to SF (3) spotting up on left wing, then cuts through to left corner.", + "actions": [ + { + "player": "offense_2", + "type": "pass", + "to_player": "offense_3", + "variant": "chest", + "intensity": "normal" + }, + { + "player": "offense_2", + "type": "cut", + "moves": [ + { + "to": { + "named": "left_corner" + } + } + ], + "intensity": "fast" + } + ], + "end_state": { + "offense_2": { + "named": "left_corner" + }, + "balls": { + "ball_1": { + "carried_by": "offense_3" + } + } + } + }, + { + "id": "frame_4", + "label": "Second Ball Screen", + "description": "PF (4) sets inside ball screen for SF (3). SF penetrates and can score, dump off to big, or kick out to wing.", + "actions": [ + { + "player": "offense_4", + "type": "screen", + "for_player": "offense_3", + "variant": "ball_screen", + "at": { + "x": -3, + "y": 9.5 + }, + "physicality": "aggressive" + }, + { + "player": "offense_3", + "type": "dribble", + "moves": [ + { + "to": { + "x": -2, + "y": 11.5 + } + } + ], + "intensity": "normal" + }, + { + "player": "offense_4", + "type": "cut", + "moves": [ + { + "to": { + "named": "left_block" + } + } + ], + "tags": [ + "roll" + ], + "intensity": "fast" + } + ], + "end_state": { + "offense_3": { + "x": -2, + "y": 11.5 + }, + "offense_4": { + "named": "left_block" + }, + "balls": { + "ball_1": { + "carried_by": "offense_3" + } + } + } + }, + { + "id": "frame_5", + "label": "Reset to PG", + "description": "SF (3) kicks out to PG (1) on wing. PG runs pick with center to reset the continuous set.", + "actions": [ + { + "player": "offense_3", + "type": "pass", + "to_player": "offense_1", + "variant": "chest", + "intensity": "normal" + }, + { + "player": "offense_5", + "type": "move", + "moves": [ + { + "to": { + "x": 0, + "y": 9.5 + } + } + ], + "intensity": "normal" + }, + { + "player": "offense_5", + "type": "screen", + "for_player": "offense_1", + "variant": "ball_screen", + "at": { + "x": 0, + "y": 9 + }, + "physicality": "aggressive" + } + ], + "end_state": { + "offense_5": { + "x": 0, + "y": 9 + }, + "balls": { + "ball_1": { + "carried_by": "offense_1" + } + } + } + } + ] +}