Skip to content

Latest commit

 

History

History
1735 lines (1653 loc) · 72.5 KB

File metadata and controls

1735 lines (1653 loc) · 72.5 KB

0t# Working with Second Representation in pmp_manip

Project Structure:

This is the UML structure of a SRProject: Structure of an SRProject

Let us compare an SRProject with it's view in the PenguinMod Editor

Editor View vs. Python Object

Editor View

Project Editor View

Python Object

from pmp_manip import get_default_config, init_config, FRProject, info_api

cfg = get_default_config()
init_config(cfg)

frproject = FRProject.from_file(file_path="path/to/my_project.pmp")
frproject.add_all_extensions_to_info_api(info_api)

srproject = frproject.to_second(info_api)
print("The contents of the project are:")
print(srproject)

Note: add_all_extensions_to_info_api is discussed later in the tutorial

Output (very long, you can skim it for now. Is analyzed in detail later):

The contents of the project are:
SRProject(
    stage=SRStage(
        scripts=[],
        comments=[],
        costumes=[
            SRVectorCostume(
                content=<Element {http://www.w3.org/2000/svg}svg at 0x7820d9c840>,
                name="backdrop1",
                file_extension="svg",
                rotation_center=(240, 180),
            ),
        ],
        sounds=[],
        costume_index=0,
        volume=100,
    ),
    sprites=[
        SRSprite(
            name="Abby",
            local_variables=[
                SRVariable(name="my slider var", current_value=30.9),
                SRVariable(name="another local var", current_value="General Kenobi!"),
            ],
            local_lists=[
                SRList(name="a local list", current_value=[]),
            ],
            local_monitors=[
                SRMonitor(
                    opcode="&sensing::draggable?",
                    dropdowns={},
                    position=(-240, 16),
                    is_visible=True,
                ),
                SRVariableMonitor(
                    readout_mode=SRVariableMonitorReadoutMode.SLIDER,
                    slider_min=30.9,
                    slider_max=100,
                    allow_only_integers=False,
                    opcode="&variables::value of [VARIABLE]",
                    dropdowns={
                        "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="my slider var"),
                    },
                    position=(-240, -54),
                    is_visible=True,
                ),
                SRMonitor(
                    opcode="&looks::[EFFECT] effect",
                    dropdowns={
                        "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
                    },
                    position=(-240, -14),
                    is_visible=True,
                ),
                SRVariableMonitor(
                    readout_mode=SRVariableMonitorReadoutMode.LARGE,
                    slider_min=0,
                    slider_max=100,
                    allow_only_integers=True,
                    opcode="&variables::value of [VARIABLE]",
                    dropdowns={
                        "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="another local var"),
                    },
                    position=(-240, -80),
                    is_visible=True,
                ),
                SRListMonitor(
                    size=(100, 102),
                    opcode="&variables::value of [LIST]",
                    dropdowns={
                        "LIST": SRDropdownValue(kind=DropdownValueKind.LIST, value="a local list"),
                    },
                    position=(-240, 78),
                    is_visible=True,
                ),
            ],
            is_visible=True,
            position=(39, 3),
            size=150,
            direction=90,
            is_draggable=True,
            uuid=UUID('a1e32a92-36fa-4a45-bc2e-9c1eca536a30'),
            scripts=[
                SRScript(
                    position=(235, 79),
                    blocks=[
                        SRBlock(
                            opcode="&customblocks::define custom block",
                            inputs={},
                            dropdowns={},
                            comment=None,
                            mutation=SRCustomBlockMutation(
                                custom_opcode=SRCustomBlockOpcode(
                                    segments=(
                                        "run frame with speed",
                                        SRCustomBlockArgument(name="speed", type=SRCustomBlockArgumentType.STRING_NUMBER),
                                        "handle keys?",
                                        SRCustomBlockArgument(name="handle keys", type=SRCustomBlockArgumentType.BOOLEAN),
                                    ),
                                ),
                                no_screen_refresh=True,
                                optype=SRCustomBlockOptype.STATEMENT,
                                main_color="#FF6680",
                                prototype_color="#e65c73",
                                outline_color="#cc5266",
                            ),
                        ),
                        SRBlock(
                            opcode="&control::if <CONDITION> then {THEN}",
                            inputs={
                                "CONDITION": SRBlockAndBoolInputValue(
                                    block=SRBlock(
                                        opcode="&operators::<OPERAND1> and <OPERAND2>",
                                        inputs={
                                            "OPERAND1": SRBlockAndBoolInputValue(
                                                block=SRBlock(
                                                    opcode="&sensing::key ([KEY]) pressed?",
                                                    inputs={
                                                        "KEY": SRBlockAndDropdownInputValue(
                                                            block=None,
                                                            dropdown=SRDropdownValue(kind=DropdownValueKind.STANDARD, value="space"),
                                                        ),
                                                    },
                                                    dropdowns={},
                                                    comment=None,
                                                    mutation=None,
                                                ),
                                                immediate=False,
                                            ),
                                            "OPERAND2": SRBlockAndBoolInputValue(
                                                block=SRBlock(
                                                    opcode="&customblocks::custom block boolean arg [ARGUMENT]",
                                                    inputs={},
                                                    dropdowns={},
                                                    comment=None,
                                                    mutation=SRCustomBlockArgumentMutation(
                                                        argument_name="handle keys",
                                                        main_color="#FF6680",
                                                        prototype_color="#e65c73",
                                                        outline_color="#cc5266",
                                                    ),
                                                ),
                                                immediate=True,
                                            ),
                                        },
                                        dropdowns={},
                                        comment=None,
                                        mutation=None,
                                    ),
                                    immediate=False,
                                ),
                                "THEN": SRScriptInputValue(
                                    blocks=[
                                        SRBlock(
                                            opcode="&looks::say (MESSAGE) for (SECONDS) seconds",
                                            inputs={
                                                "MESSAGE": SRBlockAndTextInputValue(block=None, immediate="Hello!"),
                                                "SECONDS": SRBlockAndTextInputValue(block=None, immediate="2"),
                                            },
                                            dropdowns={},
                                            comment=SRComment(
                                                position=(544.2964344861196, 207.30042684993646),
                                                size=(200, 200),
                                                is_minimized=True,
                                                text="not fully\nshown",
                                            ),
                                            mutation=None,
                                        ),
                                        SRBlock(
                                            opcode="&looks::change [EFFECT] effect by (AMOUNT)",
                                            inputs={
                                                "AMOUNT": SRBlockAndTextInputValue(block=None, immediate="25"),
                                            },
                                            dropdowns={
                                                "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
                                            },
                                            comment=None,
                                            mutation=None,
                                        ),
                                    ],
                                ),
                            },
                            dropdowns={},
                            comment=None,
                            mutation=None,
                        ),
                    ],
                ),
                SRScript(
                    position=(257, 714),
                    blocks=[
                        SRBlock(
                            opcode="&variables::set [VARIABLE] to (VALUE)",
                            inputs={
                                "VALUE": SRBlockAndTextInputValue(block=None, immediate="hello there!"),
                            },
                            dropdowns={
                                "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="another glob var"),
                            },
                            comment=None,
                            mutation=None,
                        ),
                    ],
                ),
                SRScript(
                    position=(240, 549),
                    blocks=[
                        SRBlock(
                            opcode="&customblocks::call custom block",
                            inputs={
                                "speed": SRBlockAndTextInputValue(block=None, immediate="2"),
                                "handle keys": SRBlockAndBoolInputValue(
                                    block=SRBlock(
                                        opcode="&operators::true,
                                        inputs={},
                                        dropdowns={},
                                        comment=None,
                                        mutation=None,
                                    ),
                                    immediate=False,
                                ),
                            },
                            dropdowns={},
                            comment=None,
                            mutation=SRCustomBlockCallMutation(
                                custom_opcode=SRCustomBlockOpcode(
                                    segments=(
                                        "run frame with speed",
                                        SRCustomBlockArgument(name="speed", type=SRCustomBlockArgumentType.STRING_NUMBER),
                                        "handle keys?",
                                        SRCustomBlockArgument(name="handle keys", type=SRCustomBlockArgumentType.BOOLEAN),
                                    ),
                                ),
                            ),
                        ),
                    ],
                ),
            ],
            comments=[
                SRComment(
                    position=(870, 244),
                    size=(200, 200),
                    is_minimized=False,
                    text="an independent\n comment\nwhich\nis\nfully\nshown",
                ),
            ],
            costumes=[
                SRBitmapCostume(
                    content=<PIL.PngImagePlugin.PngImageFile image mode=P size=176x144 at 0x781e6b60c0>,
                    has_double_resolution=True,
                    name="costume1",
                    file_extension="png",
                    rotation_center=(88, 72),
                ),
                SRVectorCostume(
                    content=<Element {http://www.w3.org/2000/svg}svg at 0x781e6c4200>,
                    name="Abby-a",
                    file_extension="svg",
                    rotation_center=(31, 100),
                ),
            ],
            sounds=[
                SRSound(name="Squawk", file_extension="wav", content=<pydub.audio_segment.AudioSegment object at 0x781e6bce90>),
            ],
            costume_index=1,
            volume=100,
        ),
        SRSprite(
            name="Cake",
            local_variables=[],
            local_lists=[],
            local_monitors=[],
            is_visible=True,
            position=(47.88235294117649, -104.70588235294117),
            size=80,
            direction=90,
            is_draggable=False,
            uuid=UUID('9ea54f86-9f2a-4f8b-ab0d-3f5870004020'),
            scripts=[],
            comments=[],
            costumes=[
                SRVectorCostume(
                    content=<Element {http://www.w3.org/2000/svg}svg at 0x781ed7be80>,
                    name="cake-a",
                    file_extension="svg",
                    rotation_center=(64, 50),
                ),
            ],
            sounds=[
                SRSound(name="Birthday", file_extension="wav", content=<pydub.audio_segment.AudioSegment object at 0x781e68b8c0>),
            ],
            costume_index=0,
            volume=100,
        ),
        SRSprite(
            name="Apple",
            local_variables=[],
            local_lists=[],
            local_monitors=[],
            is_visible=True,
            position=(60.58823529411765, -73.47058823529413),
            size=150,
            direction=90,
            is_draggable=False,
            uuid=UUID('1026712f-651e-43a1-9456-cf22e4555990'),
            scripts=[],
            comments=[],
            costumes=[
                SRVectorCostume(
                    content=<Element {http://www.w3.org/2000/svg}svg at 0x781e6b6d80>,
                    name="Apple",
                    file_extension="svg",
                    rotation_center=(31, 31),
                ),
            ],
            sounds=[],
            costume_index=0,
            volume=100,
        ),
    ],
    sprite_layer_stack=[
        UUID('a1e32a92-36fa-4a45-bc2e-9c1eca536a30'),
        UUID('1026712f-651e-43a1-9456-cf22e4555990'),
        UUID('9ea54f86-9f2a-4f8b-ab0d-3f5870004020'),
    ],
    global_variables=[
        SRVariable(name="another glob var", current_value="hello there!"),
        SRCloudVariable(name="☁ my cloud var", current_value="6772827383843273833275737871"),
    ],
    global_lists=[
        SRList(name="a global list", current_value=[345634, "some text"]),
        SRList(name="another g. list", current_value=[389.41, 0]),
    ],
    global_monitors=[
        SRVariableMonitor(
            readout_mode=SRVariableMonitorReadoutMode.NORMAL,
            slider_min=0,
            slider_max=100,
            allow_only_integers=True,
            opcode="&variables::value of [VARIABLE]",
            dropdowns={
                "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="another glob var"),
            },
            position=(-240, -153),
            is_visible=True,
        ),
        SRVariableMonitor(
            readout_mode=SRVariableMonitorReadoutMode.NORMAL,
            slider_min=0,
            slider_max=100,
            allow_only_integers=True,
            opcode="&variables::value of [VARIABLE]",
            dropdowns={
                "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="☁ my cloud var"),
            },
            position=(-240, -180),
            is_visible=True,
        ),
        SRListMonitor(
            size=(132, 219),
            opcode="&variables::value of [LIST]",
            dropdowns={
                "LIST": SRDropdownValue(kind=DropdownValueKind.LIST, value="a global list"),
            },
            position=(108, -180),
            is_visible=True,
        ),
        SRListMonitor(
            size=(100, 116),
            opcode="&variables::value of [LIST]",
            dropdowns={
                "LIST": SRDropdownValue(kind=DropdownValueKind.LIST, value="another g. list"),
            },
            position=(140, 64),
            is_visible=True,
        ),
        SRMonitor(
            opcode="&sensing::answer",
            dropdowns={},
            position=(-235, -25),
            is_visible=False,
        ),
        SRMonitor(
            opcode="&sensing::current [PROPERTY]",
            dropdowns={
                "PROPERTY": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="year"),
            },
            position=(-240, -128),
            is_visible=True,
        ),
        SRMonitor(
            opcode="&sensing::timer,
            dropdowns={},
            position=(-240, -104),
            is_visible=False,
        ),
    ],
    extensions=[
        SRBuiltinExtension(id="text2speech"),
        SRCustomExtension(url="https://extensions.penguinmod.com/extensions/MubiLop/numutils.js", id="numberUtilities"),
    ],
    tempo=60,
    video_transparency=50,
    video_state=SRVideoState.ON,
    text_to_speech_language=SRTTSLanguage.ENGLISH,
)

Notes:

  • I highly recommend to use a good code editor (especially VSCode), because you might want to look at the definition of e.g. a function/method or class(Alt + Left Mouse Click)
  • All listed properties and can be read, set and modified if not specified otherwise.
  • Most classes are dataclasses (specified if not), which implement these features:
    • Initialization (call class with all its properties set (listed below)) (e.g. SRVariable(name="my variable", current_value=5))
    • Comparison (==)
    • Mutability (most, a few specified ones are immutable and hashable)
    • Validation (validate method, it is recommended to just validate the SRProject as a whole => easiest, you will not need to pass in anything but info_api)
    • Conversion (most, with to_first methods, it is recommended to just convert the project as a whole)
    • Nice Representation (defines a readable __repr__)
    • Sorting (e.g. a list[SomeSRThing])

SRProject

The "root node" of a project in second representation.

SRProject.stage

  • type: SRStage(subclass of SRTarget)
  • description: The stage of the project.

SRProject.sprites

  • type: list of SRSprite(subclass of SRTarget)
  • description: The sprites of the project, excluding the stage.

SRProject.sprite_layer_stack

  • type: list of UUID(from package uuid)
  • description: The order of sprites on the stage. Must contain all sprite UUIDs(SRSprite.uuid) in any order. Last UUID means sprite is on the highest layer and is rendered on top of all other sprites. First UUID means lowest layer.

SRProject.global_variables

SRProject.global_lists

  • type: list of SRList
  • description: The names and values of the "for all sprites" lists of the project. Local Lists are stored in specific sprites, see SRSprite.local_lists

SRProject.global_monitors

SRProject.extensions

SRProject.tempo

  • type: int (minimum: 20, maximum: 500)
  • description: The music "tempo" of Scratch's Music extension in BPM (insignificant for most projects).
  • note: Equal to value of "tempo" block.
  • default value in editor: 60

SRProject.video_transparency

  • type: int or float (normally between 0 and 100) (seems not to have limits by Scratch)
  • description: The "video transparency" of Scratch's Video Sensing extension (insignificant for most projects).
  • note: Equal to input of "set video transparency to" block.
  • default value in editor: 50

SRProject.video_state

  • type: SRVideoState (enum class)
  • possible values: SRVideoState.ON, SRVideoState.ON_FLIPPED, SRVideoState.OFF
  • description: The "state" of Scratch's Video Sensing extension (insignificant for most projects).
  • note: Equal to dropdown menu of "turn video ..." block.
  • default value in editor: SRVideoState.ON

SRProject.text_to_speech_language

  • type: SRTTSLanguage (enum class) or None
  • possible values: SRTTSLanguage.ENGLISH, SRTTSLanguage.FRENCH, SRTTSLanguage.GERMAN ...
  • description: The "text to speech language" of Scratch's TTS extension (insignificant for most projects).
  • note: Equal to dropdown menu of "set language to" block.
  • default value in editor: None

Editor View Example

Python Object Example

SRProject(
    stage=SRStage(
        # shortend here
    ),
    sprites=[
        SRSprite(
            name="Abby",
            uuid=UUID('a1e32a92-36fa-4a45-bc2e-9c1eca536a30'),
            # shortend here
        ),
        SRSprite(
            name="Cake",
            uuid=UUID('9ea54f86-9f2a-4f8b-ab0d-3f5870004020'),
            # shortend here
        ),
        SRSprite(
            name="Apple",
            uuid=UUID('1026712f-651e-43a1-9456-cf22e4555990'),
            # shortend here
        ),
    ],
    sprite_layer_stack=[
        UUID('a1e32a92-36fa-4a45-bc2e-9c1eca536a30'),
        UUID('1026712f-651e-43a1-9456-cf22e4555990'),
        UUID('9ea54f86-9f2a-4f8b-ab0d-3f5870004020'),
    ],
    global_variables=[
        SRVariable(name="another glob var", current_value="hello there!"),
        SRCloudVariable(name="☁ my cloud var", current_value="6772827383843273833275737871"),
    ],
    global_lists=[
        SRList(name="a global list", current_value=[345634, "some text"]),
        SRList(name="another g. list", current_value=[389.41, 0]),
    ],
    global_monitors=[
        SRVariableMonitor(
            readout_mode=SRVariableMonitorReadoutMode.NORMAL,
            slider_min=0,
            slider_max=100,
            allow_only_integers=True,
            opcode="&variables::value of [VARIABLE]",
            dropdowns={
                "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="another glob var"),
            },
            position=(-240, -153),
            is_visible=True,
        ),
        # shortend here
    ],
    extensions=[
        SRBuiltinExtension(id="text2speech"),
        SRCustomExtension(url="https://extensions.penguinmod.com/extensions/MubiLop/numutils.js", id="numberUtilities"),
    ],
    tempo=60,
    video_transparency=50,
    video_state=SRVideoState.ON,
    text_to_speech_language=SRTTSLanguage.ENGLISH,
)

Notes

  • As we can see, all sprite UUIDs are contained in sprite_layer_stack. The order is different though. E.G. The "Cake" Sprite is on top of "Apple" in sprite_layer_stack but not in sprites.

SRTarget

Common base for SRStage and SRSprite.

SRTarget.scripts

  • type: list of SRScript
  • description: Stores all the blocks and attached comments in a sprite or the stage.

SRTarget.comments

  • type: list of SRComment
  • description: Stores all the comments, which are not attached to a block, in a sprite or the stage.

SRTarget.costumes

  • type: list of SRVectorCostume or SRBitmapCostume, see SRCostume(parent class)
  • description: Stores all the costumes of a sprite or stage.
  • note: Must have at least one costume(hint: use SRVectorCostume.create_empty for an empty default costume)

SRTarget.sounds

  • type: list of SRSound
  • description: Stores all the sounds of a sprite or stage.

SRTarget.costume_index

  • type: int (at least 0 and at most one less then the amount of costumes)
  • description: References the current costume of the sprite or stage in costumes by index.
  • default value in editor: 0

SRTarget.volume

  • type: int (minimum: 0, maximum: 100)
  • description: The local volume for playing sounds from a sprite or stage.
  • default value in editor: 100

SRStage

Represents the project stage. Inherits from SRTarget. Has no additional properties compared to SRTarget, as all global information is stored on the project directly.

Editor View Example

Python Object Example

SRStage(
    scripts=[],
    comments=[],
    costumes=[
        SRVectorCostume(
            content=<Element {http://www.w3.org/2000/svg}svg at 0x7820d9c840>,
            name="backdrop1",
            file_extension="svg",
            rotation_center=(240, 180),
        ),
    ],
    sounds=[],
    costume_index=0,
    volume=100,
)

Notes

  • As we can see, the stage has no scripts, comments and sounds, just one costume/backdrop which is empty.
  • This costume is also referenced by costume index as it is item 0.
  • For a better example, see SRSprite's Example.

SRSprite

Represents a sprite of the project. Inherits from SRTarget.

SRSprite.name

  • type: str (Blacklist: "_myself_", "_stage_", "_mouse_", "_edge_")
  • description: The name of the sprite.

SRSprite.local_variables

SRSprite.local_lists

  • type: list of SRList
  • description: The names and values of the "for this sprite only" lists of the sprite. Global Lists are stored in the project directly, see SRProject.global_lists.

SRSprite.local_monitors

SRSprite.is_visible

  • type: bool
  • description: Stores wether the sprite is shown on the stage.
  • default value in editor: True

SRSprite.position

  • type: tuple of int|float(x position) and int|float(y position)
  • description: Stores the position of the sprite on the stage. If the stage size was not changed, should be between (-240, -180) to (240, 180) (no enforced limit).
  • default value in editor: random

SRSprite.size

  • type: int | float (positive)
  • description: Stores the size of the sprite on the stage.
  • default value in editor: 100

SRSprite.direction

  • type: int | float (minimum: -180, maximum: -180)
  • description: Stores the rotation direction of the sprite on the stage.
  • default value in editor: 90 (Up: 0, Right: 90, Down: 180, Left: -90)

SRSprite.is_draggable

  • type: bool
  • description: Stores wether the sprite can be dragged across the stage in fullscreen mode.
  • default value in editor: False

SRSprite.rotation_style

  • type: SRSpriteRotationStyle (enum class)
  • possible values: SRSpriteRotationStyle.ALL_AROUND, SRSpriteRotationStyle.LEFT_RIGHT, SRSpriteRotationStyle.DONT_ROTATE in PenguinMod also SRSpriteRotationStyle.LOOK_AT, SRSpriteRotationStyle.UP_DOWN
  • description: The way the sprite behaves when rotated.
  • default value in editor: SRSpriteRotationStyle.ALL_AROUND

SRSprite.uuid

  • type: UUID(from package uuid)
  • description: A unique id for the sprite. Only used for SRProject.sprite_layer_stack.
  • note: Read-only. Can not be modified and can not be passed to SRSprite at Creation/Initialization, but is automatically set.

Editor View Example

Python Object Example

SRSprite(
    name="Abby",
    local_variables=[
        SRVariable(name="my slider var", current_value=30.9),
        SRVariable(name="another local var", current_value="General Kenobi!"),
    ],
    local_lists=[
        SRList(name="a local list", current_value=[]),
    ],
    local_monitors=[
        # shortend here
        SRMonitor(
            opcode="&looks::[EFFECT] effect",
            dropdowns={
                "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
            },
            position=(-240, -14),
            is_visible=True,
        ),
        SRVariableMonitor(
            readout_mode=SRVariableMonitorReadoutMode.LARGE,
            slider_min=0,
            slider_max=100,
            allow_only_integers=True,
            opcode="&variables::value of [VARIABLE]",
            dropdowns={
                "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="another local var"),
            },
            position=(-240, -80),
            is_visible=True,
        ),
        SRListMonitor(
            size=(100, 102),
            opcode="&variables::value of [LIST]",
            dropdowns={
                "LIST": SRDropdownValue(kind=DropdownValueKind.LIST, value="a local list"),
            },
            position=(-240, 78),
            is_visible=True,
        ),
    ],
    is_visible=True,
    position=(39, 3),
    size=150,
    direction=90,
    is_draggable=True,
    uuid=UUID('a1e32a92-36fa-4a45-bc2e-9c1eca536a30'),
    scripts=[
        SRScript(
            position=(235, 79),
            blocks=[
                SRBlock(
                    opcode="&customblocks::define custom block",
                    inputs={},
                    dropdowns={},
                    comment=None,
                    mutation=SRCustomBlockMutation(
                        custom_opcode=SRCustomBlockOpcode(
                            segments=(
                                "run frame with speed",
                                SRCustomBlockArgument(name="speed", type=SRCustomBlockArgumentType.STRING_NUMBER),
                                "handle keys?",
                                SRCustomBlockArgument(name="handle keys", type=SRCustomBlockArgumentType.BOOLEAN),
                            ),
                        ),
                        no_screen_refresh=True,
                        optype=SRCustomBlockOptype.STATEMENT,
                        main_color="#FF6680",
                        prototype_color="#e65c73",
                        outline_color="#cc5266",
                    ),
                ),
                # shortend here
            ],
        ),
        # shortend here
    ],
    comments=[
        SRComment(
            position=(870, 244),
            size=(200, 200),
            is_minimized=False,
            text="an independent\n comment\nwhich\nis\nfully\nshown",
        ),
    ],
    costumes=[
        SRBitmapCostume(
            content=<PIL.PngImagePlugin.PngImageFile image mode=P size=176x144 at 0x781e6b60c0>,
            has_double_resolution=True,
            name="costume1",
            file_extension="png",
            rotation_center=(88, 72),
        ),
        SRVectorCostume(
            content=<Element {http://www.w3.org/2000/svg}svg at 0x781e6c4200>,
            name="Abby-a",
            file_extension="svg",
            rotation_center=(31, 100),
        ),
    ],
    sounds=[
        SRSound(name="Squawk", file_extension="wav", content=<pydub.audio_segment.AudioSegment object at 0x781e6bce90>),
    ],
    costume_index=1,
    volume=100,
)

Notes

  • As we can see, the sprite has scripts, comments, two costumes(a vector and a bitmap costume) and a sound.
  • The second and active costume is also referenced by costume index as it is item 1.
  • The local monitors are not normally seperated by position. They are arranged like this for simplicity in this tutorial.

SRVariable

Represents a "for all sprites"(global) or "for this sprite only"(local) variable.

SRVariable.name

  • type: str
  • description: The name of the variable.

SRVariable.current_value

  • type: usually int, float or str, but technically bool too (e.g. Infinity is saved as 0).
  • description: The current value of the variable.

Editor View Example

Python Object Example

SRCloudVariable(name="☁ my cloud var", current_value="6772827383843273833275737871")
SRVariable(name="another local var", current_value="General Kenobi!")
SRVariable(name="my slider var", current_value=30.9)

SRCloudVariable

Inherits from SRVariable. Represents a cloud variable. Has no additional properties compared to SRVariable.

SRList

Represents a "for all sprites"(global) or "for this sprite only"(local) list.

SRList.name

  • type: str
  • description: The name of the list.

SRList.current_value

  • type: list of usually int, float and str, but technically bool too (e.g. Infinity is saved as 0).
  • description: The current value of the list.

Editor View Example

Python Object Example

SRList(name="a global list", current_value=[345634, "some text"])
SRList(name="another g. list", current_value=[389.41, 0])

SRMonitor

Represents a non-sprite-specific(global) or sprite-specific(local) monitor. Also is basis for SRVariableMonitor(subclass) and SRListMonitor(subclass)

SRMonitor.opcode

  • type: str
  • description: The "opcode"(unique identifier) of the block, the monitor is for (see SRBlock.opcode).

SRMonitor.dropdowns

  • type: dict of str keys and SRDropdownValue values
  • description: the exact dropdown settings of the monitor (e.g. "costume number/name" block). Based on the dropdowns of the block (see SRBlock.dropdowns).

SRMonitor.position

  • type: tuple of int|float(x position) and int|float(y position)
  • description: Stores the position of the monitor on the stage. If the stage size was not changed, should be between (-240, -180) to (240, 180) (no enforced limit).
  • note: You should change validation configuration to tolerant if you work with other stage sizes (See config.md, section ValidationConfig).

SRMonitor.is_visible

  • type: bool
  • description: Stores wether the monitor is currently shown on the stage.

Editor View Example

Python Object Example

Global

SRMonitor(
    opcode="&sensing::answer",
    dropdowns={},
    position=(-235, -25),
    is_visible=False,
)
SRMonitor(
    opcode="&sensing::current [PROPERTY]",
    dropdowns={
        "PROPERTY": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="year"),
    },
    position=(-240, -128),
    is_visible=True,
)
SRMonitor(
    opcode="&sensing::timer",
    dropdowns={},
    position=(-240, -104),
    is_visible=False,
)

Local

SRMonitor(
    opcode="&looks::[EFFECT] effect",
    dropdowns={
        "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
    },
    position=(-240, -14),
    is_visible=True,
)

Notes

  • The "&sensing::answer" and "&sensing::timer" monitor is not shown and therefore not shown in the image.
  • The keys of dropdowns always match with the sqaure brackets (e.g. [DROPDOWN]) in the opcode.

SRVariableMonitor

Represents the monitor of a variable value block of a global or local variable. Inherits from SRMonitor.

SRVariableMonitor.readout_mode

  • type: SRVariableMonitorReadoutMode (enum class)
  • possible values: SRVariableMonitorReadoutMode.NORMAL, SRVariableMonitorReadoutMode.LARGE, SRVariableMonitorReadoutMode.SLIDER
  • description: Stores how a variable monitors is shown(e.g. only content(=LARGE), name and content(=NORMAL), with a slider to change value(=SLIDER))
  • default value in editor: SRVariableMonitorReadoutMode.NORMAL

SRVariableMonitor.slider_min

  • type: int | float
  • description: If readout_mode is SLIDER, the minimum value you can drag the slider to.
  • default value in editor: 0

SRVariableMonitor.slider_max

  • type: int | float
  • description: If readout_mode is SLIDER, the maximum value you can drag the slider to.
  • default value in editor: 100

SRVariableMonitor.allow_only_integers

  • type: bool
  • description: If readout_mode is SLIDER, wether you can drag the slider to a non-integer value.
  • note: is set in Scratch based on wether you enter a floating point value into either the slider minimum or maximum.
  • default value in editor: True

Editor View Example

Python Object Example

SRVariableMonitor(
    readout_mode=SRVariableMonitorReadoutMode.NORMAL,
    slider_min=0,
    slider_max=100,
    allow_only_integers=True,
    opcode="&variables::value of [VARIABLE]",
    dropdowns={
        "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="☁ my cloud var"),
    },
    position=(-240, -180),
    is_visible=True,
)
SRVariableMonitor(
    readout_mode=SRVariableMonitorReadoutMode.SLIDER,
    slider_min=30.9,
    slider_max=100,
    allow_only_integers=False,
    opcode="&variables::value of [VARIABLE]",
    dropdowns={
        "VARIABLE": SRDropdownValue(kind=DropdownValueKind.VARIABLE, value="my slider var"),
    },
    position=(-240, -54),
    is_visible=True,
)

Notes

  • The red/first monitor has allow_only_integers=True as neither slider_min nor slider_max are both integers.
  • The blue/second monitor has allow_only_integers=False as slider_min is a floating point number.

SRListMonitor

Represents the monitor of a list value block of a global or local list. Inherits from SRMonitor.

SRListMonitor.size

  • type: tuple of int|float(width) and int|float(height)
  • description: Stores the size of a list monitor as it can be resized.
  • note: You should change validation configuration to tolerant if you work with other stage sizes (See config.md, section ValidationConfig).
  • default value in editor: (100, 120)

Editor View Example

Python Object Example

SRListMonitor(
    size=(100, 102),
    opcode="&variables::value of [LIST]",
    dropdowns={
        "LIST": SRDropdownValue(kind=DropdownValueKind.LIST, value="a local list"),
    },
    position=(-240, 78),
    is_visible=True,
)

SRExtension

Common base for SRBuiltinExtension and SRCustomExtension.

SRExtension.id

  • type: str
  • description: The unique id of the extension(e.g. "music" or "jgJSON").

Editor View Example

Python Object Example

SRBuiltinExtension(id="text2speech")
SRCustomExtension(
    id="numberUtilities",
    url="https://extensions.penguinmod.com/extensions/MubiLop/numutils.js",
)

SRBuiltinExtension

Represents a builtin extension that PenguinMod recognizes. Inherits from SRExtension. Has no additional properties compared to SRExtension.

SRCustomExtension

Represents a custom extension that PenguinMod does not recognize i.e. is added by URL, JS code or file. Therefore needs a url source. Inherits from SRExtension.

SRCustomExtension.url

  • type: strz
  • description: The url source for getting the extension javascript source code. Must follow one of these patterns: "http://...", "https://..." or "data:application/javascript,..."

SRTTSLanguage

Enum Class. Represents a language for Scratch's Text to Speech Extension. All supported languages are: SRTTSLanguage....

enum name/language name BCP 47 language code
ARABIC "ar"
CHINESE_MANDARIN "zh-cn"
DANISH "da"
DUTCH "nl"
ENGLISH "en"
FRENCH "fr"
GERMAN "de"
HINDI "hi"
ICELANDIC "is"
ITALIAN "it"
JAPANESE "ja"
KOREAN "ko"
NORWEGIAN "nb"
POLISH "pl"
PORTUGUESE_BRAZILIAN "pt-br"
PORTUGUESE "pt"
ROMANIAN "ro"
RUSSIAN "ru"
SPANISH "es"
SPANISH_LATIN_AMERICAN "es-419"
SWEDISH "sv"
TURKISH "tr"
WELSH "cy"

SRScript

Represents a script i.e. a connected sequence of blocks in the "Code" tab of a sprite or the stage. Similar to SRScriptInputValue.

SRScript.position

  • type: tuple of int|float(x position) and int|float(y position) Same system as with SRComment.position.
  • description: Stores the position of the script in the "Code" tab. Unlimited, but usually in the range of hundreds and thousands.

SRScript.blocks

  • type: list of SRBlock
  • description: Stores the script's sequence of blocks from top to bottom.

Editor View Example

Python Object Example

SRScript(
    position=(235, 79),
    blocks=[
        SRBlock(
            opcode="&customblocks::define custom block",
            inputs={},
            dropdowns={},
            comment=None,
            mutation=SRCustomBlockMutation(
                custom_opcode=SRCustomBlockOpcode(
                    segments=(
                        "run frame with speed",
                        SRCustomBlockArgument(
                            name="speed", 
                            type=SRCustomBlockArgumentType.STRING_NUMBER,
                        ),
                        "handle keys?",
                        SRCustomBlockArgument(
                            name="handle keys", 
                            type=SRCustomBlockArgumentType.BOOLEAN,
                        ),
                    ),
                ),
                no_screen_refresh=True,
                optype=SRCustomBlockOptype.STATEMENT,
                main_color="#FF6680",
                prototype_color="#e65c73",
                outline_color="#cc5266",
            ),
        ),
        SRBlock(
            opcode="&control::if <CONDITION> then {THEN}",
            inputs={
                "CONDITION": SRBlockAndBoolInputValue(
                    # shortend here
                ),
                "THEN": SRScriptInputValue(
                    # shortend here
                ),
            },
            dropdowns={},
            comment=None,
            mutation=None,
        ),
    ],
)
SRScript(
    position=(420, 1022),
    blocks=[
        SRBlock(
            opcode="&sensing::distance to ([OBJECT])",
            inputs={
                "OBJECT": SRBlockAndDropdownInputValue(
                    block=SRBlock(
                        opcode="&sound::length of ([SOUND])?",
                        inputs={
                            "SOUND": SRBlockAndDropdownInputValue(
                                block=None,
                                dropdown=SRDropdownValue(kind=DropdownValueKind.SOUND, value="Squawk"),
                            ),
                        },
                        dropdowns={},
                        comment=None,
                        mutation=None,
                    ),
                    dropdown=SRDropdownValue(kind=DropdownValueKind.SPRITE, value="Sprite2"),
                ),
            },
            dropdowns={},
            comment=None,
            mutation=None,
        ),
    ],
)

Notes

  • The second example is from another project.
  • As the second example shows, even single reporter/boolean etc. blocks are seperate scripts.

SRBlock

Represents a single block in a script. Can be any shape of block(e.g. square, round, hat).

SRBlock.opcode

  • type: str
  • description: The unique identifier for it's kind of block.

SRBlock.inputs

  • type: dict of str keys and SRInputValue values (only of it's subclasses though)
  • description: The arguments fields of the block and their values. Includes text, number fields, round dropdowns one can insert blocks into and all others except for square dropdowns.

SRBlock.dropdowns

  • type: dict of str keys and SRDropdownValue values
  • description: The argument fields of the block and their values. Only includes square dropdowns, not round dropdowns one can insert blocks into.

SRBlock.comment

  • type: SRComment or None
  • description: The optional attached comment of the block.
  • default value in editor: None`

SRBlock.mutation

  • type: SRMutation or None
  • description: The optional mutation of the block for some opcodes(kinds of blocks). Most blocks do not need one.
  • default value in editor: None`

Editor View Example

Python Object Example

SRBlock(
    opcode="&control::if <CONDITION> then {THEN}",
    inputs={
        "CONDITION": SRBlockAndBoolInputValue(
            block=SRBlock(
                opcode="&operators::<OPERAND1> and <OPERAND2>",
                inputs={
                    "OPERAND1": SRBlockAndBoolInputValue(
                        # shortend, see below
                    ),
                    "OPERAND2": SRBlockAndBoolInputValue(
                        # shortend, see below
                    ),
                },
                dropdowns={},
                comment=None,
                mutation=None,
            ),
            immediate=False,
        ),
        "THEN": SRScriptInputValue(
            blocks=[
                # shortend, see below
            ],
        ),
    },
    dropdowns={},
    comment=None,
    mutation=None,
)

Full "CONDITION" input

SRBlockAndBoolInputValue(
    block=SRBlock(
        opcode="&operators::<OPERAND1> and <OPERAND2>",
        inputs={
            "OPERAND1": SRBlockAndBoolInputValue(
                block=SRBlock(
                    opcode="&sensing::key ([KEY]) pressed?",
                    inputs={
                        "KEY": SRBlockAndDropdownInputValue(
                            block=None,
                            dropdown=SRDropdownValue(kind=DropdownValueKind.STANDARD, value="space"),
                        ),
                    },
                    dropdowns={},
                    comment=None,
                    mutation=None,
                ),
                immediate=False,
            ),
            "OPERAND2": SRBlockAndBoolInputValue(
                block=SRBlock(
                    opcode="&customblocks::custom block boolean arg [ARGUMENT]",
                    inputs={},
                    dropdowns={},
                    comment=None,
                    mutation=SRCustomBlockArgumentMutation(
                        argument_name="handle keys",
                        main_color="#FF6680",
                        prototype_color="#e65c73",
                        outline_color="#cc5266",
                    ),
                ),
                immediate=True,
            ),
        },
        dropdowns={},
        comment=None,
        mutation=None,
    ),
    immediate=False,
)

Full "THEN" input

SRScriptInputValue(
    blocks=[
        SRBlock(
            opcode="&looks::say (MESSAGE) for (SECONDS) seconds",
            inputs={
                "MESSAGE": SRBlockAndTextInputValue(block=None, immediate="Hello!"),
                "SECONDS": SRBlockAndTextInputValue(block=None, immediate="2"),
            },
            dropdowns={},
            comment=SRComment(
                position=(544.2964344861196, 207.30042684993646),
                size=(200, 200),
                is_minimized=True,
                text="not fully\nshown",
            ),
            mutation=None,
        ),
        SRBlock(
            opcode="&looks::change [EFFECT] effect by (AMOUNT)",
            inputs={
                "AMOUNT": SRBlockAndTextInputValue(block=None, immediate="25"),
            },
            dropdowns={
                "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
            },
            comment=None,
            mutation=None,
        ),
    ],
)

Notes

  • The python object is split for readability.
  • As we can see, blocks and (sub-)scripts have a nested structure.

SRInputValue

Represents a single input field of a block. Can be any kind of field (e.g. text, number, round dropdown) except for a square dropdown. Common base for

these properties might but MUST NOT exist, the subclasses specify below which properties they support:

SRInputValue.blocks

  • type: list of SRBlock
  • description: Stores the subscript's sequence of blocks from top to bottom (e.g. the "then" section of the "if" block).
  • note: Only exists for instances of SRScriptInputValue

SRInputValue.block

SRInputValue.immediate

  • type: str or bool (depends on subclass)
  • description: the "immediate" value of the input value i.e. if the default value if no block is dragged into the input.
  • note: Only exists for instances of SRBlockAndTextInputValue and SRBlockAndBoolInputValue.

SRInputValue.dropdown

Editor View and Python Object Example

See the example of SRBlock.

SRBlockAndTextInputValue

Inherits from SRInputValue.

SRBlockAndTextInputValue.immediate

  • type: str (does not apply to other subclasses)
  • description: the "immediate" text value of the input value i.e. if the text default value if no block is dragged into the input.
  • note: str type does not apply to other subclasses.

SRBlockAndDropdownInputValue

Inherits from SRInputValue.

SRBlockAndBoolInputValue

Inherits from SRInputValue.

SRBlockAndBoolInputValue.immediate

  • type: bool (does not apply to other subclasses)
  • description: the "immediate" on/off switch value of the input value i.e. if the on/off switch default value if no block is dragged into the input.

SRBlockOnlyInputValue

Inherits from SRInputValue.

SRScriptInputValue

Inherits from SRInputValue. Similar to SRScript.

SREmbeddedBlockInputValue

Inherits from SRInputValue. Must have a block. The opcode of that block is also constrained.

SREmbeddedBlockInputValue.block

  • type: SRBlock, NOT None
  • description: Stores the block inserted into the input. Must have one specific opcode.

SRDropdownValue

Represents a single dropdown field of a block. Can only be a square dropdown, which do not support inserting blocks into.

SRDropdownValue.kind

  • type: DropdownValueKind
  • description: Stores the kind of thing the dropdown value refers to (e.g. VARIABLE, SPRITE, OBJECT or STANDARD).

SRDropdownValue.value

  • type: almost always str but rarely int (for costume, backdrop and sound selection by index) and bool too.
  • description: Stores the actual value of the dropdown value.

Editor View Example

Python Object Example

SRBlock(
    opcode="&looks::change [EFFECT] effect by (AMOUNT)",
    inputs={
        "AMOUNT": SRBlockAndTextInputValue(block=None, immediate="25"),
    },
    dropdowns={
        "EFFECT": SRDropdownValue(kind=DropdownValueKind.STANDARD, value="color"),
    },
    comment=None,
    mutation=None,
)
SRBlock(
    opcode="&sensing::distance to ([OBJECT])",
    inputs={
        "OBJECT": SRBlockAndDropdownInputValue(
            block=None,
            dropdown=SRDropdownValue(kind=DropdownValueKind.OBJECT, value="mouse-pointer"),
        ),
    },
    dropdowns={},
    comment=None,
    mutation=None,
)

Notes

  • The second example is from another project.

DropdownValueKind

Enum Class. Represents a kind of dropdown value i.e. what it references if anything. All value kinds are: DropdownValueKind....

enum name reference
STANDARD nothing
SUGGESTION nothing
FALLBACK nothing
VARIABLE a variable
LIST a list
BROADCAST_MSG a broadcast message
STAGE the stage
SPRITE a sprite
MYSELF the sprite the block is in
OBJECT e.g. the mouse pointer, the stage edge
COSTUME a costume of the current sprite by name(str value)
or by index(int value)
BACKDROP a backdrop by name(str value) or by index(int value)
SOUND a sound by name(str value) or by index(int value)

SRMutation

Stores additional information special to some kinds of blocks. Only needed for some block opcodes(kinds of blocks). Common base for:

SRCustomBlockArgumentMutation

Inherits from SRMutation. Used and required only by opcodes "&customblocks::custom block text arg [ARGUMENT]" and "customblocks::custom block boolean arg [ARGUMENT]".

SRCustomBlockArgumentMutation.argument_name

  • type: str
  • description: the name of the custom block argument which the argument reporter block is for.

SRCustomBlockArgumentMutation.main_color

  • type: str (hex color code)
  • description: the main color of the "define" block the argument reporter block is for.
  • default value in editor: "#FF6680"

SRCustomBlockArgumentMutation.prototype_color

  • type: str (hex color code)
  • description: the main color of the inner block of the "define" block the argument reporter block is for.
  • default value in editor: "#FF4D6A"

SRCustomBlockArgumentMutation.outline_color

  • type: str (hex color code)
  • description: the outline color of the inner block of the "define" block the argument reporter block is for.
  • default value in editor: "#FF3355"

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRCustomBlockArgumentMutation(
    argument_name="handle keys",
    main_color="#FF6680",
    prototype_color="#e65c73",
    outline_color="#cc5266",
)

SRCustomBlockMutation

Inherits from SRMutation. Used and required only by opcodes "&customblocks::define custom block" and "&customblocks::define custom block reporter".

SRCustomBlockMutation.custom_opcode

  • type: SRCustomBlockOpcode(SRCustomBlockOpcode is immutable and hashable)
  • description: Stores the name and argument field names and kinds of the custom block.

SRCustomBlockMutation.no_screen_refresh

  • type: bool
  • description: Wether the "Run without screen refresh" box was ticked when creating the custom block.
  • default value in editor: False

SRCustomBlockMutation.optype

  • type: SRCustomBlockOptype
  • description: What shape of block the custom block is (e.g. square statement, boolean, reporter).
  • default value in editor: SRCustomBlockMutation.STATEMENT

SRCustomBlockMutation.main_color

  • type: str (hex color code)
  • description: the main color of the "define" block.
  • default value in editor: "#FF6680"

SRCustomBlockMutation.prototype_color

  • type: str (hex color code)
  • description: the main color of the inner block of the "define" block.
  • default value in editor: "#FF4D6A"

SRCustomBlockMutation.outline_color

  • type: str (hex color code)
  • description: the outline color of the inner block of the "define" block the argument reporter block is for.
  • default value in editor: "#FF3355"

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRCustomBlockMutation(
    custom_opcode=SRCustomBlockOpcode(
        segments=(
            "run frame with speed",
            SRCustomBlockArgument(name="speed", type=SRCustomBlockArgumentType.STRING_NUMBER),
            "handle keys?",
            SRCustomBlockArgument(name="handle keys", type=SRCustomBlockArgumentType.BOOLEAN),
        ),
    ),
    no_screen_refresh=True,
    optype=SRCustomBlockOptype.STATEMENT,
    main_color="#FF6680",
    prototype_color="#e65c73",
    outline_color="#cc5266",
)

SRCustomBlockCallMutation

Inherits from SRMutation. Used and required only by opcode "&customblocks::call custom block".

SRCustomBlockCallMutation.custom_opcode

  • type: SRCustomBlockOpcode(SRCustomBlockOpcode is immutable and hashable)
  • description: Stores the labels and argument field names and kinds of the custom block, this block will call, to reference it.

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRCustomBlockCallMutation(
    custom_opcode=SRCustomBlockOpcode(
        segments=(
            "run frame with speed",
            SRCustomBlockArgument(name="speed", type=SRCustomBlockArgumentType.STRING_NUMBER),
            "handle keys?",
            SRCustomBlockArgument(name="handle keys", type=SRCustomBlockArgumentType.BOOLEAN),
        ),
    ),
)

SRExpandableIfMutation

Inherits from SRMutation. Used and required only by opcode "&control::{{EXPANDABLE IF-THEN-ELSE CHAIN}}".

SRExpandableIfMutation.branch_count

  • type: int
  • description: the amount of branches

SRExpandableIfMutation.ends_in_else

  • type: bool
  • description: wether the last branch is an else

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRExpandableIfMutation(
    branch_count=3,
    ends_in_else=True,
)

SRExpandableOperatorMutation

Inherits from SRMutation. Used and required only by opcodes "&operators::{{EXPANDABLE MATH CHAIN}}", "&operators::{{EXPANDABLE BOOL CHAIN}}", "&operators::{{EXPANDABLE COMPARE CHAIN}}".

SRExpandableOperatorMutation.operations

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRExpandableOperatorMutation(
    operations=[SRExpandableOperatorMenu.SUBTRACT, SRExpandableOperatorMenu.MULTIPLY],
)

SRExpandableJoinMutation

Inherits from SRMutation. Used and required only by opcode "&operators::{{EXPANDABLE JOIN CHAIN}}".

SRExpandableJoinMutation.input_count

  • type: int (minimum: 1)
  • description: the count of inputs

Editor View Example

The mutation itself can not be seen in the editor, only the block:

Python Object Example

SRExpandableJoinMutation(
    input_count=4,
)

SRCustomBlockOpcode

Represents the "opcode"(see SRBlock.opcode) of a custom block i.e. stores the labels and argument field names and kinds of a custom block. Immutable and Hashable.

SRCustomBlockOpcode.segments

  • type: tuple of str or SRCustomBlockArgument
  • description: Stores the labels and argument field names and kinds of the custom block. A str item represents a label, a SRCustomBlockArgument represents an argument of the custom block.

SRCustomBlockArgument

Represents an argument of a SRCustomBlockOpcode. Immutable and Hashable.

SRCustomBlockArgument.name

  • type: str (not empty)
  • description: the name of the argument.

SRCustomBlockArgument.type

  • type: SRCustomBlockArgumentType (enum class)
  • possible values: SRCustomBlockArgumentType.STRING_NUMBER, SRCustomBlockArgumentType.BOOLEAN
  • description: the kind of the argument (string or number vs. boolean).

SRCustomBlockOptype

Enum Class. Represents the shape of a custom block (e.g. square statement, boolean, reporter) All possible values are: SRCustomBlockOptype....

enum name
STATEMENT
ENDING_STATEMENT
STRING_REPORTER
NUMBER_REPORTER
BOOLEAN_REPORTER

Editor View Example

SRExpandableOperatorMenu

Enum Class. Represents the dropdown values between the inputs of an expandable operator All possible values are: SRExpandableOperatorMenu....

enum name
ADD
SUBTRACT
MULTIPLY
DIVIDE
POWER
GREATER
GREATER_EQ
LESS
LESS_EQ
EQUAL
STRICT_EQUAL
NOT_EQUAL
AND
OR
XOR
NAND
NOR
XNOR

SRComment

Represents a comment, which can be either atttached to a block or "freely floating" in the "Code" tab of a sprite or the stage.

SRComment.position

  • type: tuple of int|float(x position) and int|float(y position)
  • description: Stores the position of the comment in the "Code" tab. Unlimited, but usually in the range of hundreds and thousands. Same system as with SRScript.position.

SRComment.size

  • type: tuple of int|float(width) and int|float(height) minimum: (52, 32)
  • description: Stores the size of a comment.
  • default value in editor: (200, 200)

SRComment.is_minimized

  • type: bool
  • description: Wether it is collapsed i.e. only a part of the comment is shown.
  • default value in editor: False

SRComment.text

  • type: str
  • description: The actual text content of the comment.

Editor View Example

Python Object Example

SRComment(
    position=(870, 244),
    size=(200, 200),
    is_minimized=False,
    text="an independent\n comment\nwhich\nis\nfully\nshown",
)
SRBlock(
    opcode="&looks::say (MESSAGE) for (SECONDS) seconds",
    inputs={
        "MESSAGE": SRBlockAndTextInputValue(block=None, immediate="Hello!"),
        "SECONDS": SRBlockAndTextInputValue(block=None, immediate="2"),
    },
    dropdowns={},
    comment=SRComment(
        position=(544.2964344861196, 207.30042684993646),
        size=(200, 200),
        is_minimized=True,
        text="not fully\nshown",
    ),
    mutation=None,
)

SRCostume

Represents a costume in the "Costumes" tab of a sprite or a backdrop in the "Backdrops" tab of the stage. Common base for SRVectorCostume and SRBitmapCostume.

SRCostume.name

  • type: str
  • description: The name of the costume. Must be unique for each costume in a sprite.

SRCostume.file_extension

SRCostume.rotation_center

  • type: tuple of int|float(x position) and int|float(y position)
  • description: The coordinate the costume is centered at i.e. will be rotated around as a vector from the top left.

SRCostume.content

  • note: exists on both possible subclasses just with a different type.

SRVectorCostume

Represents a costume in "Vector" mode in the "Costumes" tab of a sprite or a backdrop in the "Backdrops" tab of the stage. It is based on an SVG image.

SRVectorCostume.content

  • type: _Element(from package lxml.etree)
  • description: The actual SVG image basis of the costume as an XML element tree.

Editor View Example

Python Object Example

SRVectorCostume(
    name="Abby-a",
    file_extension="svg",
    rotation_center=(31, 100),
    content=<Element {http://www.w3.org/2000/svg}svg at 0x781e6c4200>,
)

Notes

  • Yes I know. lxml Elements have a terrible __repr__ :(.

SRBitmapCostume

Represents a costume in "Bitmap" mode in the "Costumes" tab of a sprite or a backdrop in the "Backdrops" tab of the stage. It is based on an bitmap image (e.g. a PNG).

SRBitmapCostume.content

  • type: Image(from package PIL.Image)
  • description: The actual bitmap image basis of the costume as created by pillow's Image.open. PenguinMod seems to limit and reduce image size to (480, 360) when importing from a file.

SRBitmapCostume.has_double_resolution

  • type: bool
  • description: Pretty useless. Seems to always be True. PenguinMod seems to limit and reduce image size to (480, 360) when importing from a file.

Editor View Example

Python Object Example

SRBitmapCostume(
    name="costume1",
    file_extension="png",
    rotation_center=(88, 72),
    has_double_resolution=True,
    content=<PIL.PngImagePlugin.PngImageFile image mode=P size=176x144 at 0x781e6b60c0>,
)

SRSound

Represents a sound in the "Sounds" tab of a sprite or the stage.

SRSound.name

  • type: str
  • description: The name of the sound. Must be unique for each sound in a sprite.

SRSound.file_extension

  • type: str
  • description: The extension of the sound if saved as a file. Usually "wav" or "mp3".

SRSound.content

  • type: AudioSegment(from package pydub_ng)
  • description: The actual audio segment basis of the sound as created by pydub_ng's AudioSegment.from_file.

Editor View Example

Python Object Example

SRSound(
    name="Squawk", 
    file_extension="wav", 
    content=<pydub.audio_segment.AudioSegment object at 0x781e6bce90>,
)

References

  • For a documentation overview and all pages of the tutorial, see docs/index.md
  • For an instruction on Getting info on opcodes(this is further ahead in the tutorial), see docs/doc_api.md
  • Next Page: Analyzing and Editing Projects, see docs/analyze_edit.md