Do not download from this page! The very latest version, with bugfixes, improved gameplay, and a hassle-free 'download and double-click' stand-alone Windows binary, lives at Sinister Ducks on GitHub.
Presented by nitrofurano
Smallest use of py26 syntax incompatible with py25
Presented by jtrain
Presented by richard
Presented by Akake
Ratings (show detail)
Day 3: Hills added, ducks fight and feathers flutter about
FYI: unblanced gameplay in Sinister Duckes
I belatedly realise that it's only fair for to me to point out to all of you who are presumably *still playing* Sinister Ducks that it's very very hard to actually die. (ie. let enough enemy ducks bash you on the head so that you run out of feathers and plummet from the sky.) Even if you did - you have infinite lives! So you can just stop playing once you've had enough.
oh no we're not
what I learned from the Sinister Ducks
Sinister Ducks is our first PyWeek submission. We had a great time putting it together. Many thanks to Richard and everyone else who contributes to making PyWeek happen, and to all the other entrants for their work and passion and joy and tears and advice.
It is about the simplest game we could think up. We didn't set out with the following goal in mind, but after a day or so it became clear we were pretty much converging on the gameplay of the arcade classic 'Joust'. After realising that, we didn't go out of our way to avoid it - after all, Joust was really fun!
We don't have wild innovation, terrific production values, nor any variation or depth. But it *is* a game, more or less, that provides an amount of fun within its small remit, flapping around bouncing off other birds heads, and we got it uploaded within the deadline, and can point at it and say 'I made this'. That makes me happy.
My lessons from PyWeek:
FOR FUN: PREFER ITERATION OVER PREDICTION
Even with such a simple game, it was surprising to me how difficult the core mechanics were to nail down. For several days we imagined that collecting feathers would give birds a more powerful flap, but then we discovered that this wasn't actually a very desireable thing for the player, so we had to scrap that. So, plan to iterate on game mechanics is one lesson that obviously I've heard others say many times, but I'm learning all over again for myself now.
GET FAMILIAR WITH YOUR TOOLS
We could have worked two or three times faster if we had any experience with the (parts of) the libraries we were using. In particular, for us, we should have seen ahead of time that we would end up doing a 2D sprite game, because that just seems easiest and simplest, and hence I should have invested a little time up front understanding a few of the libraries for doing sprites, by hacking out a spritey demo or game, long before PyWeek.
VALUE GOALS & HANDS-ON EXPERIENCE
I dabble in games and graphics programming in my spare time, although the majority of that time goes into undirected exporation of whatever I'm finding most interesting at the time. Having a tangible goal with a short timeframe like this was a good change of pace for me, because it forced me to grapple with the mundane nitty gritty (like digging out that microphone headset and actually recording some dying-duck noises), rather than just imagining the process and thinking 'yeah yeah, I could do that'.
All four of us on the team are professional software engineers. We like to think of ourselves as being relatively agile and enlightened, as corporate programming drones go. It's clear though that the different environment and parameters of PyWeek caused us to struggle against some of our ingrained mindsets. One of us, when creating a three-line .ini file to store some settings for the game, found himself thinking about how best to acquire / implement a general-purpose config parser - luckily he caught himself in time. I, however, actually spent (wasted?) a few hours refactoring our sprite/image handling code. Although the code is now better looking for it, I didn't then have any time left over to build anything on top of the refactored code, so the user-visible difference is naught. With such a tight timeline, at least for a team like ours that is inexperienced in this domain, and has limited free time at our disposal, everything has to be focused on immediate and visible payoff. What can I do that will improve the game this hour? Within ten minutes?
Right. Time for chicken soup, then some judging...
oops - no binaries
Wouldn't be fun if it was all straightforward, right?
feathers give "stronger flaps" : doesn't work
In the player's case, there seems to be no utility to stronger flaps. Flaps which are too weak mean the player has to flap like crazy to stay aloft. Flaps which are too strong make the player hard to control - you overshoot a lot. Playing either way is annoying, and it seems bad to make the player have to contend with either of these circumstances.
Also, changing enemy flap power made the rudimentary AI harder to tune and get right, with no actual payoff.
So I'm thinking of scrapping variable strength flaps. Collecting feathers gives the player points (with flashy combos, I hope), and gives the enemies more smarts (I hope)
a note on scoring
We had been scoring 10 points per collected feather. A friend wandered by and pointed out that if we made the scoring dependent on the number of consecutively collected feathers (without hitting any enemies) then it gives the player incentive to rush around attacking as many enemies as possible BEFORE then rushing to collect all the resulting feathers before they fall off the bottom of the screen.
The code change is tiny, and the movement of all the entities is unchanged, yet the difference on gameplay is incredible. A palpable urgency is injected, a modicum of tactics, geometric scoring rewards for playing well, and a risk-reward dynamic, since waiting before collecting feathers risks losing them off the bottom of the screen.