{"id":20299848,"url":"https://github.com/python-ninja-hebi/wonderworld","last_synced_at":"2025-10-19T09:22:17.098Z","repository":{"id":178032490,"uuid":"604237090","full_name":"Python-Ninja-Hebi/wonderworld","owner":"Python-Ninja-Hebi","description":"Data-oriented Python Game Engine","archived":false,"fork":false,"pushed_at":"2024-01-23T13:26:30.000Z","size":1047,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-14T16:16:28.454Z","etag":null,"topics":["game-engine","pygame","pygame-library","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Python-Ninja-Hebi.png","metadata":{"files":{"readme":"README.ipynb","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-02-20T16:14:59.000Z","updated_at":"2024-02-14T15:49:23.000Z","dependencies_parsed_at":"2024-01-23T14:55:08.466Z","dependency_job_id":null,"html_url":"https://github.com/Python-Ninja-Hebi/wonderworld","commit_stats":null,"previous_names":["python-ninja-hebi/wonderworld"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Python-Ninja-Hebi%2Fwonderworld","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Python-Ninja-Hebi%2Fwonderworld/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Python-Ninja-Hebi%2Fwonderworld/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Python-Ninja-Hebi%2Fwonderworld/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Python-Ninja-Hebi","download_url":"https://codeload.github.com/Python-Ninja-Hebi/wonderworld/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233876725,"owners_count":18744248,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game-engine","pygame","pygame-library","python"],"created_at":"2024-11-14T16:16:32.089Z","updated_at":"2025-09-22T18:32:07.999Z","avatar_url":"https://github.com/Python-Ninja-Hebi.png","language":"Python","readme":"{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"f3f374ee-78f2-4c76-bd7c-53fe608c9ade\",\n   \"metadata\": {},\n   \"source\": [\n    \"# wonderworld - Data-oriented Python Game Engine\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"fce9d0b5-0b81-4048-ab23-d48138f3601e\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"img/logo.png\\\" width=\\\"128\\\" align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"ae0b1338-2a91-40a3-a5c7-f9aa1ce2638b\",\n   \"metadata\": {},\n   \"source\": [\n    \"* **Game Engine** implemented on **Database Engine (in memory with pandas)**\\n\",\n    \"* **world** is a **database**\\n\",\n    \"* **archetype** is a **table**\\n\",\n    \"* **entity** is a **row(id)**\\n\",\n    \"* **componenten** is one **column**\\n\",\n    \"* **system** is a **function**\\n\",\n    \"* **query** is a **database query**\\n\",\n    \"* **Now** with **pydantic** https://docs.pydantic.dev/latest/\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"f4e8bd63-0105-43b4-a2e4-47b4388a08e3\",\n   \"metadata\": {},\n   \"source\": [\n    \"*I have long wanted to program games in Pygame using the Entity Component System (ECS) game design pattern. Once when I looked at the Bevy game framework in Rust, I was hooked. I wanted something like that in Python too.\\n\",\n    \"Since I couldn't find such a framework anywhere, I started developing a Python ECS framework myself -* **wonderworld**\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"ab577b53-d604-4cf3-9a87-d7b41b87a272\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Entity Component System ECS\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"a57006ef-0e7b-4072-8e91-5aabfc739eae\",\n   \"metadata\": {},\n   \"source\": [\n    \"The data-oriented programming (DOP) approach tries to strictly separate data and program from each other.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"bd482601-3598-4e57-a583-13eaf344f983\",\n   \"metadata\": {},\n   \"source\": [\n    \"One way to do this is with the **Entity Component System** (ECS) design pattern.\\n\",\n    \"\\n\",\n    \"A **component** in the ECS design pattern contains only data.\\n\",\n    \"\\n\",\n    \"Examples:\\n\",\n    \"\\n\",\n    \"* Transform(x,y) - TransformComponent\\n\",\n    \"* Speed (x,y) - SpeedComponent\\n\",\n    \"* Sprite(image) - ImageComponent\\n\",\n    \"\\n\",\n    \"A component does not contain any processing logic.\\n\",\n    \"\\n\",\n    \"An **entity** is a game object, such as the knight. It consists of any number of components and does not itself contain any data or program logic. A unique ID linked to the components via an internal data structure is sufficient for the implementation of an entity.\\n\",\n    \"\\n\",\n    \"A **system** contains the complete processing logic, but no own data. A game can consist of any number of systems. A system reads components and transforms their current state into another.\\n\",\n    \"\\n\",\n    \"For example, the **Movement system** retrieves all speed components (SpeedComponents) and transform components (PositionComponent) in order to calculate the new position from them.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"7034ab26-5c14-4ae2-9ee3-851234071c10\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"img/system.png\\\" width=\\\"512\\\"  hspace=20 align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"20592fa5-ca08-4a80-869b-29af74851808\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Bevy\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"589a0967-1a23-4987-84a0-d8eb00973a60\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"https://bevyengine.org/assets/bevy_logo_dark.svg\\\" width=\\\"256\\\" style=\\\"background-color:black;\\\" hspace=20 align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"af81b4c4-0f8e-4b9a-a6e1-26b02dbc6982\",\n   \"metadata\": {},\n   \"source\": [\n    \"https://bevyengine.org\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"52f5c455-9b0e-4b53-8598-bde0ef661808\",\n   \"metadata\": {},\n   \"source\": [\n    \"## pygame\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"c9bd7ff7-6124-4061-8601-1a285e5d0aca\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"https://www.pygame.org/images/logo_lofi.png\\\" width=\\\"256\\\" style=\\\"background-color:black;\\\" hspace=20 align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"adc227f6-e595-4fd9-b6e3-0f24dfe5f2a6\",\n   \"metadata\": {},\n   \"source\": [\n    \"https://www.pygame.org\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"8225736a-f412-44ef-917a-d5d42898b435\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Example first.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"ce973014-a027-4cf9-886a-dd379b9bc8aa\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"img/first.gif\\\" width=\\\"256\\\" align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"id\": \"c6d9c7c3-b869-494b-b7df-71ede81b51c6\",\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"pygame 2.1.2 (SDL 2.0.18, Python 3.9.16)\\n\",\n      \"Hello from the pygame community. https://www.pygame.org/contribute.html\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from wonderworld import *\\n\",\n    \"\\n\",\n    \"PADDLE_VELOCITY: float = 180.0\\n\",\n    \"\\n\",\n    \"class Paddle(Component):\\n\",\n    \"    pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def setup():\\n\",\n    \"    commands = get_commands()\\n\",\n    \"    assets = get_resource(Assets)\\n\",\n    \"\\n\",\n    \"    # asset_server = get_resource(AssetServer)\\n\",\n    \"    # image_handle = asset_server.load(\\\"box.png\\\");\\n\",\n    \"\\n\",\n    \"    image_handle = assets.add(create_image(color=pygame.Color('white'),\\n\",\n    \"                                           size=Vector2(10.0, 100.0)))\\n\",\n    \"\\n\",\n    \"    # camera\\n\",\n    \"    commands.spawn(Camera2dBundle(camera=Camera(),\\n\",\n    \"                                  transform=Transform(translation=Vector2(0,0),\\n\",\n    \"                                                      rotation=0,\\n\",\n    \"                                                      scale=Vector2(0, 0))))\\n\",\n    \"\\n\",\n    \"    # paddle\\n\",\n    \"    commands.spawn(SpriteBundle(sprite=Sprite(image=image_handle),\\n\",\n    \"                                transform=Transform(translation=Vector2(100, 100),\\n\",\n    \"                                                    rotation=0,\\n\",\n    \"                                                    scale=Vector2(0, 0)),\\n\",\n    \"                                visibility=Visibility(visible=True))) \\\\\\n\",\n    \"        .insert(Paddle())\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def input():\\n\",\n    \"    time = get_resource(Time)\\n\",\n    \"    keyboard_input = get_resource(Keyboard)\\n\",\n    \"\\n\",\n    \"    for transform, in Query(Transform, With(Paddle)):\\n\",\n    \"        paddle_move = time.delta_seconds * PADDLE_VELOCITY\\n\",\n    \"        if keyboard_input.pressed(K_UP):\\n\",\n    \"            transform.translation.y = transform.translation.y - paddle_move\\n\",\n    \"\\n\",\n    \"        if keyboard_input.pressed(K_DOWN):\\n\",\n    \"            transform.translation.y = transform.translation.y + paddle_move\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == \\\"__main__\\\":\\n\",\n    \"    App().insert_resource(ClearColor(color=pygame.Color('black'))) \\\\\\n\",\n    \"        .add_plugins(DefaultPlugins()) \\\\\\n\",\n    \"        .add_startup_system(setup) \\\\\\n\",\n    \"        .add_system(input) \\\\\\n\",\n    \"        .run()\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"67145359-33b5-41c6-af74-c71681bd9734\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Example ping.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"d25c8267-2051-436d-bbae-78fdad3a4702\",\n   \"metadata\": {},\n   \"source\": [\n    \"\u003cimg src=\\\"img/ping.gif\\\" width=\\\"256\\\" align=\\\"left\\\"\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\u003cbr\u003e\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"id\": \"b7856bd8-3958-497d-bec8-9bbf04e0d884\",\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"pygame 2.1.2 (SDL 2.0.18, Python 3.9.16)\\n\",\n      \"Hello from the pygame community. https://www.pygame.org/contribute.html\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from wonderworld import *\\n\",\n    \"\\n\",\n    \"HEIGHT = 600\\n\",\n    \"WIDTH = 800\\n\",\n    \"\\n\",\n    \"PADDLE_WIDTH: float = 10.0\\n\",\n    \"PADDLE_HEIGHT: float = 100.0\\n\",\n    \"PADDLE_VELOCITY: float = 180.0\\n\",\n    \"PADDLE_MAX_MOVE: float = HEIGHT - PADDLE_HEIGHT\\n\",\n    \"PADDLE_MIN_MOVE: float = 0\\n\",\n    \"\\n\",\n    \"BALL_WIDTH: float = 10.0\\n\",\n    \"BALL_VELOCITY: Vector2 = Vector2(160.0, 160.0)\\n\",\n    \"\\n\",\n    \"LINE_WIDTH: float = 2.0;\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Score(Resource):\\n\",\n    \"    left: int\\n\",\n    \"    right: int\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Ball(Component):\\n\",\n    \"    pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Paddle(Component):\\n\",\n    \"    up_key: int\\n\",\n    \"    down_key: int\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Velocity(Component):\\n\",\n    \"    value: Vector2\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class LeftText(Component):\\n\",\n    \"    pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class RightText(Component):\\n\",\n    \"    pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def setup():\\n\",\n    \"    commands = get_commands()\\n\",\n    \"    assets = get_resource(Assets)\\n\",\n    \"\\n\",\n    \"    # camera\\n\",\n    \"    commands.spawn(Camera2dBundle(camera=Camera(),\\n\",\n    \"                                  transform=Transform()))\\n\",\n    \"\\n\",\n    \"    # ball\\n\",\n    \"    ball_handle = assets.add(create_image(color=pygame.Color('white'),\\n\",\n    \"                                          size=Vector2(BALL_WIDTH, BALL_WIDTH)))\\n\",\n    \"\\n\",\n    \"    commands.spawn(SpriteBundle(sprite=Sprite(image=ball_handle),\\n\",\n    \"                                transform=Transform(translation=Vector2(100, 100)),\\n\",\n    \"                                visibility=Visibility(visible=True))) \\\\\\n\",\n    \"        .insert(Velocity(value=BALL_VELOCITY.copy())) \\\\\\n\",\n    \"        .insert(Ball())\\n\",\n    \"\\n\",\n    \"    # line\\n\",\n    \"    line_handle = assets.add(create_image(color=pygame.Color('white'),\\n\",\n    \"                                          size=Vector2(LINE_WIDTH, HEIGHT)))\\n\",\n    \"    commands.spawn(SpriteBundle(sprite=Sprite(image=line_handle),\\n\",\n    \"                                transform=Transform(translation=Vector2(WIDTH / 2, 0)),\\n\",\n    \"                                visibility=Visibility(visible=True)))\\n\",\n    \"    # paddle_left\\n\",\n    \"    left_handle = assets.add(create_image(color=pygame.Color('white'),\\n\",\n    \"                                          size=Vector2(PADDLE_WIDTH, PADDLE_HEIGHT)))\\n\",\n    \"    commands.spawn(SpriteBundle(sprite=Sprite(image=left_handle),\\n\",\n    \"                                transform=Transform(translation=Vector2(0.0,\\n\",\n    \"                                                                        HEIGHT / 2.0 - PADDLE_HEIGHT / 2)),\\n\",\n    \"                                visibility=Visibility(visible=True))) \\\\\\n\",\n    \"        .insert(Paddle(up_key=K_w, down_key=K_a))\\n\",\n    \"\\n\",\n    \"    # paddle_right\\n\",\n    \"    right_handle = assets.add(create_image(color=pygame.Color('white'),\\n\",\n    \"                                           size=Vector2(PADDLE_WIDTH, PADDLE_HEIGHT)))\\n\",\n    \"    commands.spawn(SpriteBundle(sprite=Sprite(image=right_handle),\\n\",\n    \"                                transform=Transform(translation=Vector2(WIDTH - PADDLE_WIDTH,\\n\",\n    \"                                                                        HEIGHT / 2.0 - PADDLE_HEIGHT / 2)),\\n\",\n    \"                                visibility=Visibility(visible=True))) \\\\\\n\",\n    \"        .insert(Paddle(up_key=K_UP, down_key=K_DOWN))\\n\",\n    \"\\n\",\n    \"    # score\\n\",\n    \"    asset_server = get_resource(AssetServer)\\n\",\n    \"    font_size = 64\\n\",\n    \"    commands.spawn(Text2dBundle(\\n\",\n    \"        text =  Text(text=\\\"0\\\",\\n\",\n    \"                font =  asset_server.load(\\\"fonts/FiraSans-Bold.ttf\\\",AssetType.FONT,size=font_size),\\n\",\n    \"                font_size = font_size,\\n\",\n    \"                color = Color('white')\\n\",\n    \"            ),\\n\",\n    \"        transform = Transform(translation=Vector2(WIDTH/4.0,200.)\\n\",\n    \"    ))).insert(LeftText())\\n\",\n    \"    commands.spawn(Text2dBundle(\\n\",\n    \"        text=Text(text=\\\"0\\\",\\n\",\n    \"                  font=asset_server.load(\\\"fonts/FiraSans-Bold.ttf\\\", AssetType.FONT, size=font_size),\\n\",\n    \"                  font_size=font_size,\\n\",\n    \"                  color=Color('white')\\n\",\n    \"                  ),\\n\",\n    \"        transform=Transform(translation=Vector2(3 *WIDTH / 4.0, 200.)\\n\",\n    \"                            ))).insert(RightText())\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def input():\\n\",\n    \"    time = get_resource(Time)\\n\",\n    \"    keyboard = get_resource(Keyboard)\\n\",\n    \"\\n\",\n    \"    for (paddle, transform) in Query((Paddle, Transform)):\\n\",\n    \"        paddle_move = time.delta_seconds * PADDLE_VELOCITY\\n\",\n    \"        if keyboard.pressed(paddle.up_key):\\n\",\n    \"            transform.translation.y = max(PADDLE_MIN_MOVE, transform.translation.y - paddle_move)\\n\",\n    \"        if keyboard.pressed(paddle.down_key):\\n\",\n    \"            transform.translation.y = min(PADDLE_MAX_MOVE, transform.translation.y + paddle_move)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def move_ball():\\n\",\n    \"    time = get_resource(Time)\\n\",\n    \"    for (transform, velocity) in Query((Transform, Velocity), With(Ball)):\\n\",\n    \"        transform.translation += velocity.value * time.delta_seconds\\n\",\n    \"\\n\",\n    \"        if transform.translation.y \u003c= 0 or transform.translation.y + BALL_WIDTH \u003e= HEIGHT:\\n\",\n    \"            velocity.value.y = - velocity.value.y\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def collides():\\n\",\n    \"    for ball_transform, velocity in Query((Transform, Velocity), With(Ball)):\\n\",\n    \"        ball_size = Vector2(BALL_WIDTH, BALL_WIDTH)\\n\",\n    \"        for paddle_transform, in Query(Transform, With(Paddle)):\\n\",\n    \"            paddle_size = Vector2(PADDLE_WIDTH, PADDLE_HEIGHT)\\n\",\n    \"            if collide_aabb(ball_transform.translation, ball_size,\\n\",\n    \"                            paddle_transform.translation, paddle_size):\\n\",\n    \"                velocity.value.x = - velocity.value.x\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def score():\\n\",\n    \"\\n\",\n    \"    score = get_resource(Score)\\n\",\n    \"\\n\",\n    \"    for transform, in Query(Transform,With(Ball)):\\n\",\n    \"        if transform.translation.x \u003c 0:\\n\",\n    \"            score.right += 1\\n\",\n    \"            transform.translation = Vector2(WIDTH/2,HEIGHT/2)\\n\",\n    \"        elif transform.translation.x \u003e WIDTH:\\n\",\n    \"            score.left += 1\\n\",\n    \"            transform.translation = Vector2(WIDTH/2,HEIGHT/2)\\n\",\n    \"\\n\",\n    \"def show_score():\\n\",\n    \"    score = get_resource(Score)\\n\",\n    \"\\n\",\n    \"    for text, in Query(Text,With(LeftText)):\\n\",\n    \"        text.text =  f\\\"{score.left}\\\"\\n\",\n    \"\\n\",\n    \"    for text, in Query(Text,With(RightText)):\\n\",\n    \"        text.text = f\\\"{score.right}\\\"\\n\",\n    \"\\n\",\n    \"if __name__ == \\\"__main__\\\":\\n\",\n    \"    App() \\\\\\n\",\n    \"        .insert_resource(ClearColor(color=pygame.Color('black'))) \\\\\\n\",\n    \"        .insert_resource(WindowDescriptor(\\n\",\n    \"        title=\\\"wonderworld ping\\\",\\n\",\n    \"        width=WIDTH,\\n\",\n    \"        height=HEIGHT,\\n\",\n    \"        resizable=False)) \\\\\\n\",\n    \"        .insert_resource(Score(left=0, right=0)) \\\\\\n\",\n    \"        .add_plugins(DefaultPlugins()) \\\\\\n\",\n    \"        .add_startup_system(setup) \\\\\\n\",\n    \"        .add_system(input) \\\\\\n\",\n    \"        .add_system(move_ball) \\\\\\n\",\n    \"        .add_system(collides) \\\\\\n\",\n    \"        .add_system(score) \\\\\\n\",\n    \"        .add_system(show_score) \\\\\\n\",\n    \"        .run()\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"d55e968e-f43b-4e60-b5cc-68ea1e615576\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"c9a06c9b-eb2a-42b9-9aed-03659c2321c9\",\n   \"metadata\": {},\n   \"source\": [\n    \"* Let's build an Entity Component System from scratch (part 1) https://devlog.hexops.com/2022/lets-build-ecs-part-1/\\n\",\n    \"* Let's build an Entity Component System (part 2): databases https://devlog.hexops.com/2022/lets-build-ecs-part-2-databases/\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"51de7e74-6cc1-4231-9bfe-7b07acf68ea7\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3 (ipykernel)\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.10.13\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-ninja-hebi%2Fwonderworld","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpython-ninja-hebi%2Fwonderworld","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpython-ninja-hebi%2Fwonderworld/lists"}