Skip to content

Recreating Scratch examples in Python

The Scratch Team's starter-project catalogue links public, remixable projects with visible block source. This chapter starts with two of those projects and separates a runnable adaptation from a translation plan.

Hide and Seek: runnable adaptation

Original: Hide and Seek by Scratchteam. The original block graph was inspected on 2026-10-11.

The target alternates between hiding and appearing at random positions. Clicking it increments the score, plays a sound, and relocates it. The Python adaptation keeps those mechanics with original geometric artwork and a generated chime. It omits the introductory speech bubble and keeps click relocation within the same visible bounds as the timed loop.

Map blocks to Python

Original Scratch sequence itchy description
Green flag; set score; go to center; show events.on_start(reset_round, ...)
Forever; hide; wait; choose random x/y; show; wait control.forever(hide_then_appear)
When sprite clicked; change score; sound; relocate events.on_click(found_target)
Pick random operators.random_number(low, high)

Name the sequences with lists

The runnable source is included directly, so the book and executable example stay aligned:

from itchy import control, events, looks, operators, sound
from itchy import move
# SPDX-License-Identifier: CC-BY-SA-2.0
# Adapted from Scratchteam's Hide and Seek (project 10128368).
# https://scratch.mit.edu/projects/10128368/
# Original artwork/sound replaced; instruction bubble omitted.
from pathlib import Path

from itchy.game import Command, Costume, Game, Num, Sound, Sprite

assets = Path(__file__).parent / "assets"
player_costume = Costume(assets / "player.svg")
score = Num("score")
chime = Sound("Found", assets / "collect.wav")

reset_round: list[Command] = [score.reset(), move.to(0, 0), looks.show()]
relocate = move.to(operators.random_number(-200, 200), operators.random_number(-140, 140))
hide_then_appear: list[Command] = [looks.hide(), control.wait(1), relocate, looks.show(), control.wait(0.7)]
found_target: list[Command] = [score.add(1), sound.play(chime), relocate]

target = Sprite(
    name="Target",
    costume=player_costume,
    sounds=(chime,),
    scripts=(
        events.on_start(reset_round, control.forever(hide_then_appear)),
        events.on_click(found_target),
    ),
)
game = Game("Hide and Seek — Python recreation", (score,), (target,))

reset_round, hide_then_appear, and found_target are ordinary typed lists. relocate is a single reusable command whose random reporters are evaluated by Scratch on each execution, not when Python constructs it.

Run and test

These examples live in the itchy source repository. Run uv sync and activate .venv before using the commands below. For your own project, use itchy init instead.

itchy run

Select Hide and Seek from the menu, then click the visible target. Build its standalone export with itchy build; the file is dist/hide-and-seek.sb3.

Browser tests load that exported project, wait for the target to appear, click its rendered position, check the score, and restart. Timer and randomness behavior is tested in the browser; the headless tick adapter does not control wall-clock waits or random seeds.

Attribution

games/hide_and_seek.py is marked CC BY-SA 2.0, with the original project and author credited in its header. The Scratch website's historical terms source documents the remix license used for shared projects of this period. The license text describes attribution and share-alike terms. No original costume or sound files are bundled in this adaptation. This example license does not assign a license to the rest of itchy.

Pong Starter: verified translation plan

Original: Pong Starter by Scratchteam, whose project notes credit @natalie. The original block graph was inspected on 2026-10-11.

Original behavior Translation status
Ball initializes at a position and direction Supported with go_to and point_direction
Ball moves and bounces at edges forever Supported with forever, move, and bounce
Paddle follows mouse x Supported with move.set_x(sensing.mouse_x())
Touch paddle; sound; randomized turn; move away Supported with touching, play_sound, if_, random_number, and turn
Touch losing color; stop stop supported; color sensing available through predicate("sensing_touchingcolor", ...)

This is a roadmap derived from the actual source, not a runnable Pong port. Translate each independent event script using the current builders, then test paddle movement, contact response, loss, and restart before including the exported game in the showcase. Preserve the original author and project attribution if adapting its scripts or assets.

Add another recreation

Choose a source with visible scripts and an explicit reuse license. Record the project URL, author, inspected version/date, and any additional credits. Compare its block graph against the supported API. Replace or attribute assets, document intentional changes, and add behavioral tests. Prefer small complete recreations to snippets that silently omit important scripts.