It's a wrap
I'm happy to return to PyWeek after a few years where having little children made it seem impossible. I worked pretty intensely this week but also took a lot of time out to do family things, more than in PyWeeks of old, when I could spend the whole of the first Sunday and final Saturday programming.
AI is picking up a lot of the slack, and o1/o3 and Claude 3.7 are pretty incredible tools for writing game engine maths. But dumb too, particularly at project-wide scale. I got best results asking them to produce self-contained demos, bugfixing them, and working to integrate that into the whole. It's not quite vibe coding: it's maddening trying to unpick what they did and why it doesn't work in a different context.
AI totally changes the way we program and it's not realistic to put that genie back in the bottle. The skill for PyWeek is being able to collaborate effectively with AI, and I think I'm getting better at that, and leaning into it more.
I'm pretty happy with my game. It has the vibe I wanted: lush tropical vegetation, peaceful river, and the challenge of steering a canoe with one paddle while trying to do it quickly.
The original idea was more towards kayaking in a flowing river, and I did get o3-mini-high to produce a Navier-Stokes solver but I never tried running it: it was always a stretch goal and I while have some understanding of flow-mapping shaders, I first needed the environment in which to set that system.
A pivotal (and probably bad) decision was to switch from pygfx (high level wgpu-based) to moderngl (low-level OpenGL) plus moderngl_window (pretty low). I did this because I needed to write shaders for the water effects and pygfx has an undocumented shader API, while AI was doing a great job with moderngl. In principle moderngl_window has model loading and scene management, but it turns out it is much less complete than pygfx - it doesn't support the instanced rendering I needed for vegetation or the ability to customise the uniforms and attributes in order to do shadow mapping. In the end I wrote a lot, a lot of moderngl code, reimplementing moderngl_windows's OBJ loading and scene management in order to add instancing and shadows. I guess whichever way you go, a 10% gap means you end up rewriting 70% of the tool you're using.
Another reason I chose moderngl was that I could pull in bits of Wasabi2D for UI, which afaict moderngl_window doesn't really do. But in the end that didn't happen. I had a brief look at what it would take and it's hard because Wasabi2D is pretty tightly coupled. However I used Wasabi2D for some coroutine code that made the paddle interaction easier to write (I wanted to make the paddle animation better, but alas, no time).
I hope you enjoy the game. Let me know if you have any issues running it!
(log in to comment)