Dev Week 2

a pixel art of a clothing washer machine made using Aseprite.

This week we got Gentoo installed on a Microsoft SP4 tablet!! This includes touch support so that we can make game sprites using Aseprite.

A washing machine sprite to wash all your dirty data!

We started developing a Qt6/Pyside6-like API in Python to create in-game GUIs for Pygame. It's on Github but I've already switched away from Python (see more info from next week's post) so it probably won't get any more updates.

A pygame-qt window with a single window widget containing many widgets (they would have eventually been implemented as buttons) that have configurable padding on each side individually. The colors are generated for each element one time at startup and stored in memory. The "button" widgets were added in a for-loop allowing a dynamic number to be added. The QHBoxLayout grows to the right as new widgets are appended. The handlebar would have eventually served as a way to click-drag the window to move it around.

This week as we continued down the rabbit hole of trying to add strict typing to everything in Python, we hit some hard limits, either in Python's capabilities or in my understanding. We had previously upgraded the project to Python 3.13 (from 3.12) specifically for the default argument in typing.TypeVar(..., default=...). However, as we proceeded to use the default argument, we ran into issues with Python typing itself and with Mypy (see ticket here). Here's the code:

from typing import TypeVar, Generic

class GameNode(Generic['GameNodeType']):
    pass

GameNodeType = TypeVar('GameNodeType', bound=GameNode, default=GameNode)

This short block of code is enough to insta-crash Mypy: "AssertionError: Must not defer during final iteration." We didn't dig into it any further, but it would seem that it was delaying trying to figure something out about the typing and ended up never doing it, so it gave up.

We see in this code block, our goal was to create a generic composite GameNode (which can support regular game loop behavior like update, handle input, and render), but we don't want to have to type GameNode[GameNode] or something every time we subclass it. The generic should automatically take on another GameNode so it continues to accept any GameNodes as children without having to specify the generic type every time. Maybe I'm misusing Python typing, but even so, the experience felt lacking. Next week, I'll talk about switching from Python to C++.

Posted in Dev

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.