KREEP, first week of March.

Hello everyone!

Yep, I know it is not the first week of March 🙂 , but I think a little irony never hurts + it is helpful to make one remember, that “man proposes god disposes”!
The first week of March was the planned finish (maybe even release!) date for the Steam update for Operation KREEP. Albeit it was a vague plan, still, here I’m close to three weeks after and I’m not even finished with the extra content.
Planning is hard, keeping yourself to your plans is even harder 😦 …

Oh well, at least huge progress this week 🙂 ! Here they are, the new goody goodies I’ve added to Operation KREEP:
Three new mutators made it into the update and they are fun as hell 😀 .

Chaos KREEP in action. This is what I call “hard” mode, or “really chaotic” mode. The KREEP not only spawns it’s “KREEP-lings” every second or so, but moves around the map too.

Slow missiles is really weird 😀 , players can race their projectiles 😛 .

I suspect Explosive vandalism is going to be a real game changer but only in case of short matches, or it will enforce careful play, so players don’t blow the whole map up in an instance by shooting at large group of props accidentally 🙂 .

Besides implementing the new mutators, I made some subtle modifications on the user interface. Since I plan to add a few new levels next week, the number of levels are going to be close to twenty, and I realized, that navigating a rather lengthy list with only the arrow keys is going to be cumbersome…
I didn’t want to overhaul the whole UI, so instead of adding mouse control or redesigning to have a grid based level selection, I’ve implemented page-up/down, home, and end key support. While I was at it, I added entry number indicators to make the scroll-bars more useful.

That’s a wrap for this week. I think it’s still too early to declare a finish date, especially based on my progress during the last two months, but I’m getting close now, so I think by the end of next month, the new content and the Steam build is going to be mature enough to release it.

As always, I’m open for critique and suggestions, and stay tuned for the next update!

Magic Item Tech, achievement unlocked.

Hello there!

It looks like I fail to stick to my plans regarding this development blog, and sadly overall to becoming a bit more organized 😦 . Instead of listing the well known and common indie dev. distractions which bog me down too I jump onto this months “achievement”: the achievement system 😛 .

When I designed the Steam update for KREEP and selected the features that will make the cut ( self imposed time constraints, that I already ran out of 😦 ) Steam achievements were no. 1 on my priority list. So I knew, achievements have to happen, but when I sat down to design the software changes required, I came to the conclusion, that simply implementing the whole thing in the game project would be messy and foolish, and the bulk of the achievement system could be implemented as a “low level” service in my framework code!

I wrote down the following points, as the design guidelines and requirements for this lower level service:

  • An achievement is not much more than a boolean flag (state) whether it’s unlocked or not, and some accompanying rules about unlocking circumstances and presentation (description).
  • The game logic itself already implements fine details regarding when and how something relevant to achievements occur and it only needs to signal these events to the system (this is the only thing that has to be added to an otherwise complete game code for fully working achievements).
  • The game code shouldn’t need to know or care about whether the achievement state is read from a file or downloaded from a network back-end, or gathered using the SteamAPI. This logic is especially irrelevant for the part of the code where certain events unlock achievements, but at the meantime the service should support multiple persistency modes, since not everyone is a Steam user and achievements would be a nice addition to non-Steam buyers too!

This is what I came up with and implemented:

A little more description:

  • The API user interacts with the AchivementSystem class almost exclusively.
  • For unlocking achievements “events” (string or integer IDs) have to be fired/signaled to the system, e.g.: “XYZKilled”, “Level1Complete”, “BossDead” etc…
  • For finer control of some achievements, time-frames (again string or integer IDs) can be started and stopped on demand, e.g.: “First10SecondsOfRound”, “JustRespawned” etc…
  • The AchievementDescription instances are shipped as a game asset, the AchievementState instances are gathered using the persistency manager, and they are matched with their correct description using a string ID (external reference). The API user can not directly influence or change the state of these objects. It must be done ( for the sake of clean code and my sanity 😛 ) through the AchivementSystem using “events”.
  • Achievements can have a counter (optional), for “collection” based achievements, e.g.: “Kill 1000 zombies”, “Respawn a 100 times in one match”
    These counters can be accumulative (“Achieve 100 kills”) or they can be connected to time-frames and reset immediately upon a stopped time-frame (“Achieve 100 kills within the first 10 minutes of a match”).
  • State persistency management is automatic and almost entirely hidden from the game logic, only configuration and implementation selection required: instantiating the wanted AchievementPersistencyManager implementation e.g: File, Network, SteamAPI. Persistency handling is “session” based, so unlocked/progressed/reset achievements can be collected and flushed together (but it is optional), which is usually useful for both file and network based serialization.

A small video footage of a sample built using the system:

Here is an achievement description from the sample in XML format:

    <Name>Back out seconds</Name>
    <Description>Hold down backspace for 10 seconds!</Description>
        <Format>{1,2}/{0} ({2})</Format>

It describes the “Backspace” achievement, keeping state using a counter (10 seconds), progressing for every “HoldBackspace” event fired (this is fired in the sample every second if the backspace key is down), and resetting if the “BackspaceDown” time-frame is stopped (this is started when backspace key is pressed, and stopped when it is released).

There are other useful features in the system, which I didn’t mention yet, and a lot of planned ideas to extend it (like multiple named counters for achievements) but I often end up with a huge writing so I’m calling it a day at this point 🙂 .

Hopefully the next writing will be about concrete new features in KREEP and maybe about a release date on Steam 😉 .
Stay tuned!