March 2025 challenge: “Downstream”
Scuffy - Game Complete!
Posted by mit-mit on 2025/03/30 11:34
Riverborn - It's a wrap
Posted by mauve on 2025/03/30 10:06
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!
Golden Hound - My diary entry
Posted by speedlimit35 on 2025/03/30 00:58
Thank you for checking out my game. You can leave any bugs or feedback with my game here.
I am a little worried that my game is very laggy, so any feedback is appreciated!
Thank you!
speedlimit35
Anyport - Entry uploaded
Posted by Cosmologicon on 2025/03/30 00:33
Let me know if you have any trouble with the game. Thanks for trying it out!
Awaking - Awaking– How to play
Posted by Walkercito on 2025/03/29 22:45
Although it's not finished or even playable due to the circumstances I mentioned in last entries, here's the how to play and what you should expect ミ●﹏☉ミ.
First, you need to get the game running, for that you need to install the package manager I'm using (uv) or you can directly install the following dependencies using `pip`
pygame-ce 2.5.3
pytmx 3.32
asyncio
If you want to use uv, you can install it with the following command:
# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex
# Linux/MacOS
curl -LsSf https://astral.sh/uv/install.sh | sh
After that you should be able to use `uv sync`, so, try it:
uv sync
That command should install the the dependencies and to start running you put:
uv run main.py
Remember that all of this HAS to be done inside of the project's folder!
Awaking is a 5-minute minimalist experience where you play as a character who must choose between breaking the current (helping others break free from addiction) or going with the flow (accepting the status quo). Your decisions determine which of the two alternate endings you'll reach, reflecting the game jam's downstream theme through simple yet meaningful narrative.
- [W/A/S/D] -> To move in four directions
- [E] -> To interact with an NPC when the indicator above and them appears
- [ESC] -> To open settings inside the game
- [Mouse] -> Only for the main menu and settings
Two bars track your struggle in the bottom-left corner:
- Influence (Blue): Your power to change minds
- Energy (Golden): The stamina to keep fighting
The city flows like a river of glowing screens. You move against the current, offering weathered books to strangers drowning in digital light. Some shrug you off—their rejection drains your resolve. Others hesitate, and in that moment, you pour your energy into persuasion. Even standing still has consequences; the tide erodes your will differently when you choose not to act.
Three types of people drift through this neon stream: the willing, the resistant, and those too far gone. Learn their rhythms—your success depends on reading the subtle currents in their eyes.
(Mechanically: Each NPC interaction dynamically affects your Influence and Energy bars. Manage both resources carefully to reach the ending you desire.)
Even though the game is full of beautiful animations and love thanks to CanIIAweekee, the circumstances of our environment didn't allow us to make the game playable.
Right now, if you don't have a *decent* PC, the game runs at 2-7 FPS, even with baked lights enabled. I could improve performance using numpy, but I wasn't able to commit the changes due to a blackout. Moving on from this first issue... (ー_ー゛)
The lack of music and sound effects is not intentional. We planned to use a heartbeat sound when Influence and Energy were draining to emphasize the fading light. A menu background track, a soft piano theme with wind sounds for gameplay, and sound effects for NPC rejection were also prepared, but, unfortunately, we couldn't add them due to the same issue. The credits screen, as you might have noticed, is also incomplete for the same reason.
Regarding the endings, we considered two possibilities. One occurs when the player does nothing or is constantly rejected, causing their energy to reach zero. In this case, they would lose their color and turn black in a cinematic sequence. The second ending happens when the player surpasses the 87% threshold. At that point, all NPCs begin rejecting help, leading to a loss of Influence and Energy. As Influence decreases, the player's light fades with them, and in near-total darkness, their heartbeat grows louder. When they reach zero, a cinematic sequence would show the NPCs they helped returning the favor. Unfortunately, right now, it just transitions to a white screen. (٥↼_↼)
Thank you all for your comments, and a huge thanks to the PyWeek team for organizing such an amazing event! Despite the difficulties, it was really fun to participate!! ( /^ω^)/♪♪
Bad Ending– Frame 01
Bad Ending– Frame 02
Bad Ending – Frame 03
Bad Ending – Frame 04

Bad Ending – Frame 05
———————
This is the planned logo and app icon. Couldn't be implemented.
DownStream - Day 7
Posted by Anders on 2025/03/29 22:32
Down the toilet - First and last note
Posted by gurkwaan on 2025/03/29 21:20
The Current of Time - ときのながれ (Tokinonagare) - Day 7 - Wrap up.
Posted by KNKWasTaken on 2025/03/29 18:55
If end is well, all is well.Well, today turned out to be more hectic than I thought.
I added a very simple menu to the game so that people actually get time to prepare before the story.
I had to create a new soundtrack too, due to the fact that the original soundtrack was just too "noisy" (which was justified, since it was a synth made form a faucet.) Listen to it here.
I created two new sprites for adding depth to the story,
Also made it so that the keys are configurable through a file `keyconfig.json`
Created a README file and some other license files.
Finally, as of writing this, I'm uploading the final zip file as the submission.
This will probably be the last diary entry from me this PyWeek. While I did go with the "it's a feature, not a bug" mentality, it's still a good outcome.
Not uploading images as you'll probably see the game soon.
Awaking - Lights, Influence and a Generator
Posted by Walkercito on 2025/03/29 11:37
I read your comments on the last (and first) entry, and I wanted to say thank you for the attention :'3. It really means a lot to me. Now, moving on to today's entry!
Even though there's not much time left, I think I can manage to at least provide a simple working prototype of the planned gameplay. I might stay up all night to try and finish the main mechanic (⌐■-■)
Today, I finished the entire player light and Influence system. These two are proportional in gameplay—if one goes up, the other goes up, and if one goes down, the other follows. I wanted to add some sounds to this, like a heartbeat for when your energy is dropping and tense music for when the light is fading away, but I might not be able to include them. Maybe just the background music ( /^ω^)/♪♪
The light system has the option to be calculated in real time (giving a smoother and prettier look when fading or growing) or baked for potato PCs like mine :D. The baked version pre-renders all the frames of the light using an async loading screen and then saves them in a dictionary for easy use if enabled.
I was able to make this progress thanks to a power generator, since I’ve been without electricity since yesterday ಥ‿ಥ
There are still some things left to polish before moving on to packaging and testing, but I think I can make it!
See you in a few hours, hopefully, final entry!
Drifty Ducky - All done, I think
Posted by Spears Dracona on 2025/03/29 02:52
I've got my game to a point that I'm pretty happy with and uploaded what will probably be the final version.
I've really only participated in the past in an art role so programming a whole game myself was new to me. My history in game development is a lot of unfinished projects that only get as far as making art or starting and never finishing a tutorial to try and learn a game engine. This is the first time I have ever seen a whole game through from beginning to end. It's simple, but it's something significant for me.
When I say I went in blind, I'm not kidding. I got online Saturday night and remembered, "Oh yeah, there's a PyWeek going on at the end of this month," got on the website, and saw that it was starting in seven minutes. I got it in my head that I was going to participate, registered an entry, voted on the themes, and spent the rest of the remaining minutes Googling what the best libraries for making 2D games in Python were. I decided to roll with Arcade, for no other reason than arcades are cool.
Most of my decisions in creating this game were just spur-of-the-moment thoughts that I acted on with no real rhyme or reason.
I went with the first "downstream" idea that popped into my head, a game about a rubber ducky floating down a stream. Seemed simple enough.
Now when I say I'm not much of a programmer, I mean that I am definitely not a programmer by trade and I don't have a degree in it. I took a Python class in 2012. I get the urge to dabble in game development periodically but it's not something I've stuck with consistently. And the past couple of years of my life have been pure insanity. What skills I do have are extremely rusty.
I spent the first couple of days Googling "How to ___ in Python Arcade" for just about everything. On Sunday, I felt like I was in over my head just getting the basics down. I was seriously concerned I might not be able to finish even a very simple prototype this week. On Monday I finally got to a point where I was coding things without looking everything up. Then on Tuesday, I made a ton of progress and actually got to a point where the main features of the game were finished. I started adding little things that I thought would make it feel more fun or more polished, like simple animations for the sprites, keeping track of the player's high score, a nicer title screen and game over screen, little effects when you kill enemies, more things that show up in the background, stuff like that. I threw together some simple sound effects in Jsfxr (https://sfxr.me/) and found some cute music that was licensed under a Creative Commons license since I know music is outside of the scope of what I can learn to do myself in a week on top of everything else.
I got it to a point that I think it feels like a real game and I kind of love it. I've spent a lot of time just playing it for fun. I don't know if I'm just giddy because I made it myself or if it's actually really fun, but I guess I'll find out when other people play it.
I learned a lot over the course of this week, and a lot of things came back to me. There are a lot of things I could have done better. A lot of things that probably should have been separate classes or functions. I definitely want to work on making my code more modular in the future and not just throw everything in one insane mega file like I did this time.
But hey, I made a game. I made a whole game by myself. And that's something I'm proud of. I feel like I could tackle something slightly bigger and challenge myself a little bit more, and I'm kind of excited about doing it.
This was a lot of fun and I can't wait to see everyone else's games.