Monday, April 1, 2013

Where's My March 1GAM?

So, it is April 1st, past the deadline to have released my March One Game A Month, and yet I have only released this website: http://fancyfishgames.com/TripThroughTime/ , and there is no playable version of the game available anywhere. It's about a robot from a post-apocalyptic era who is sent back in time to observe the nature of humans and decide whether or not they are worth bringing back to life.


The trailer of the game, the only footage that I have released.

I'm sure you're all very patient, and are eagerly awaiting while I "look into one release option," but I regret to inform you that this has all been an April Fool's joke in bad taste. I'm not actually looking into release options at all, and have decided, aside from my friends and family, that no one should be able to play "Trip Through Time."

The world is not ready for this game.

This decision didn't come easily, as I really do want to get my games out there. However, I just feel that the world is not ready for this game. You see, in the development of this game, I wanted to have the robot travel all the way back to his "present," the year 397 A.H. (after humans). But, I am also a strong believer that games have to be realistic, and I just didn't know what the future era should look like, let alone the post-apocalyptic era. So there was only one reasonable way for me to add those eras: I invented a time machine, and both myself and my wife (Natalie Maletz, who created the art for the game) traveled into the future to gather reference material.

That's like spoiling the ending of a good book.

Now, the game and it's art was meant to only be loosely based off of the future, however, as people play-tested the game, we realized that the game was actually revealing too much of what we had seen, and I just can't in clear conscience do that to the world. That's like spoiling the ending of a good book.

So, I apologize to all followers and everyone who was excited about playing the game, but I wont be releasing it to the public. Thank you for all your interest, and please look forward to my April 1GAM. I have learned a lot from this game, and it is clear to me now that some things are best left unknown.

Monday, March 4, 2013

MIDI Music in AS3

So, for fun, I experimented with playing midi music in AS3 today, partly to see how hard it was to do, and partly to learn more about sound programming. I may have plans for this kind of stuff for future projects, but for now, it's just an experiment. Scroll to bottom if you just want to see source code.

First, why would I want to play MIDI files in AS3? Well, MIDI files are small (think kb for long songs, not mb), and very easy to manipulate. Since MIDI files contain just information about the volume, pitch, and duration (and a bunch of metadata/instruments that I wont handle, so I'll ignore in this blog post), it's trivial to edit the song, increase or decrease the tempo, and perform pitch shifts or even changing of instruments, and this can all be done dynamically. Unfortunately, for whatever reason, Flash does not support native playback of MIDI files, nor can you access the native soundbanks (instruments) to play the MIDI files from flash. I've seen some as3 projects use sockets to play the MIDI files via an external java applet, and I've seen some as3 projects that load sound bank files as well, but the first method requires an external dependency, and the second method requires loading the soundbank files for every instrument you want (which can be tens or hundreds of mb). However, there's a third option too - dynamically generating the soundbanks, and that's what I wanted to experiment with.

The idea came from as3sfxr: http://www.superflashbros.net/as3sfxr/ (which I found on the One Game A Month website). It allows you to dynamically generate sound effects with a bunch of interesting parameters. You can see some of their example sound effects on the left. However, tweaking with the parameters, I thought I could come up with some interesting instruments. You can control the start frequency and the sustain time to change the pitch and duration of a note - everything you need to play a MIDI file. To get a nice clean tone, I recommend setting everything to the defaults, and then choosing sinewave (which produces a pretty generic sinewave), but experimenting with the settings, you can create a whole set of instruments, like electronic, retro, and even real-world sounding instruments. So, I had my dynamic, tweakable "soundbank," all I needed to do was load a MIDI file and then play the generated sounds at the right times, with the right pitches and right durations.

The Instrument class handles playing a note with specified sfxr parameters. It changes the frequency and duration parameters for each note you wish to render, and then ADDS the generated sound samples to the passed buffer (at it's current position). Adding sound samples together is an approximation of two overlapping sounds playing at the same time. To be fully realistic, you would want to add the frequencies of the two clips (using a fourier transform), not the samples - but that is not only complicated, but also very computationally expensive if we're doing it on the fly, and adding the samples sounds good enough. So, if you learn one lesson from this blog post, it's that if you have two sound clips and you want to generate a new sound clip that has both of them playing at the same time, just add the samples (if you don't know what samples are, that's another topic, but feel free to ask me and I can explain it, or just look at tutorials on WAV files).

Some minor details - sfxr takes a decent amount of time to generate the samples from the parameters, so I had to cache the results for every pitch and duration the instrument came across. That sounds crazy, but computers have a lot of memory, and the same note will occur many times, so it speeds things up many times. Also, sfxr's start frequency and sustain time parameters are very unintuitive - they are numbers from 0 to 1. The static method getLengthFromS in Instrument takes an input (in seconds) and returns a sfxr value from 0-1 (or higher if it's longer than 2.something seconds, luckily I hacked sfxr to allow sustainTimes larger than 1 - I also made some other minor changes to sfxr, mainly to access private methods). The static method getFreqFromHz in Instrument takes an input frequency in hz and returns a sfxr value (clamping from 0-1 is ok here, as frequencies below 0 and above 1 sound terrible anyways). I had to see what the code was doing to figure out the mapping function, but trust me, it works, just trust these methods :P. The static method getFreqOfMidiNote in Instrument takes a midi pitch number and converts it to a frequency in hz and then calls getFreqFromHz to return the sfxr frequency for the midi pitch. This algorithm I found online, 2^((n-69)/12)*440 - basically, every 12 midi numbers is an octave, which means multiplying or dividing by two, and note 69 is an A with a hz value of 440 that's a baseline.

The Instrument class is the most important one, but we also need a way to manage tracks of notes. The Track class has a single instrument, and then an array of note start, duration and frequencies. You can add notes to it by calling addNote (they should be added in ascending order of note start for playback with MIDISound, any order is fine with CachedSound). The renderNote function renders a single note with the track's instrument to the correct position in the byte array. The render function renders ALL notes with the track's instrument to the correct position in the byte array (this can take some time). The prepare function ensures all of the notes are cached for quick playback, and runs asynchronously with a callback.

The Main class uses as3midilib (https://code.google.com/p/as3midilib/) to load the midi song and add the notes to a Track class, and then plays it. This is relatively straightforward, but MIDI files don't give you note duration, instead they have note start and note end events. So I had to keep playing notes in a hash and then when I got the note end event update the duration. I've noticed some bugs with the MIDI loading, the division value isn't always correct (which is why it's 0.6/file.division instead of 1/division), and one file had events at the wrong times, but it mainly works with a little tweaking.

Finally, I have two playback classes. CachedSound takes a ByteArray of samples and plays it in a loop. This can play a rendered midi sound from Track.render, or whatever else you want. But, the render method can take some time, so I also added a MIDISound playback class. It allows you to add tracks you want to play, prepares them all so that all of the instruments are cached, and then will render and play the full MIDI byte array at the same time (it assumes notes are in ascending order of start time to do this). It will also loop, and after the first play it will render from a cached version just like CachedSound.

That's all for this experiment. You can hear an old MIDI song of mine (composed in middle school >_>) being played with a clear sinewave here: http://fancyfishgames.com/MidiPlayer (entire swf is only 17 kb!)

You can hear the same song played using the generateBlipSelect method of SfxrParams for the instrument here: http://fancyfishgames.com/MidiPlayer/blip.html (literally change p.resetParams(); p.waveType = 2; p.decayTime = 0.15; to p.generateBlipSelect(); to in the Instrument class do this).

And the source code plus all dependencies is here: http://fancyfishgames.com/MidiPlayer/MidiPlayer.zip (undocumented, but I explained most of it above). Feel free to experiment with MIDI files and instruments! Oh yeah, the Main.status.text lines are just there to set that one line of text, feel free to remove!

If you have questions, feel free to ask!

Pandora's Box Direction


Recently, sandbox games have gained a lot of popularity. Sandbox games allow the player to be creative, and provide many options for playing and solving problems. This freedom is what makes sandbox games so interesting, but it also usually correlates to a lack of direction in the game. In linear games, the player is constantly directed, with the game difficulty slowly increasing to challenge the player and keep them engaged until the end. With sandbox games, the player is usually thrown into a world and gets to do whatever they want. But without any direction, challenge or "end," instead of keeping the player engaged, the intrigue of the game will slowly wear off and they eventually stop playing. While obviously gameplay evolution and direction could keep the player engaged longer, adding strong direction would only ruin the freedom and spirit that makes sandbox games so successful.

A very successful sandbox game that has very little direction is Minecraft. I recently played the game, and enjoyed it a lot. In the beginning, there was a simple goal: survival. There were many ways to be creative to accomplish that goal - building structures, digging trenches, mining resources, crafting equipment, growing food, etc. Eventually, my fortress became impenetrable by the enemies in the game, and direction was lost. Survival was guaranteed, and from that point on, the game was all about exploring, experimenting in the world, and being creative. The multiplayer aspect improved this part of the game, as you could show your inventions to friends and work together on building projects. However, eventually, without challenge or direction, the game started to get dull. This is not to say Minecraft is a bad game, it entertained me for a long time before it got dull. But, I think with more direction, the game could have been even better and lasted even longer. For instance, I did create a netherword portal and explore it a little out of curiosity, but given there wasn't much there of value and it was very dangerous, I stayed out of the netherword for the most part. I feel like if there was direction, a reason to enter the netherworld, that could have added a whole new part of the game where I had to leave my comfort zone and learn to deal with the new challenges and enemies of the netherworld.

A smaller, less well known game by the same developer, is called Minicraft. Minicraft was made in 48 hours, and on it's surface, it looks a lot like a 2D version of Minecraft. However, Minicraft provides direction throughout the entire game without ruining the sandbox feel. The goal of the game is not to survive, but to defeat the Air Wizard. To defeat the Air Wizard, you'll need Gem equipment, and to get Gem equipment, you'll need to go down three levels of caves, each more dangerous than the last. The game suffers from rough edges and poor balancing due to the short development time, but there is direction to the game and the difficulty increases as you progress, without FORCING the player to do anything, keeping the freedom and spirit of sandbox games.

This form of direction I like to call Pandora's Box Direction (or player-initiated direction). Whether due to curiosity or need, the player is compelled to open Pandora's Box. Like in the myth, when opened, Pandora's Box increases the challenge and difficulty of the game, forcing the player to learn how to deal with that challenge by manipulating the sandbox. Quite possibly, in order to deal with the new threat, they feel compelled to open a new Pandora's Box, helping them deal with the first threat but releasing an even bigger threat. This creates a chain of direction, that always keeps the player on their toes and continues to give them reason to build and modify their sandbox. This chain allows the developer to balance the challenges at each box, but ultimately leaves the decision of when to open the box up to the player. This kind of direction can also create a plot, where at each "box" they learn something new, and are lead slowly but surely to some final confrontation. The direction could be completely linear, but because the player is given freedom of when to open the boxes, and freedom of how to deal with the new challenges, the game retains it's creative sandbox feel. It's like recreating that exciting first stage of Minecraft many times, each time with new enemies, challenges, and resources to keep the player engaged. For example, in Minecraft, mining diamonds could unleash a dragon from underground, who is angry you stole its treasure. Because the dragon can fly and burn wooden structures, players would have to completely rethink their defenses. And perhaps the best way to slay a dragon is to use a magic system, which requires resources unique to the netherworld, opening up a whole new pandora's box.

Sandbox games without direction can still be great games, but I personally believe that the challenges should continue evolving, so the difficulty never bottoms out. A player shouldn't quit the game because they end up finding it dull, but because they have reached some climax and ending. The Pandora's Box method is the best way to achieve this while staying within the open style that sandbox games create. I plan to experiment with this method and hope others do too!

Monday, February 25, 2013

Being Indie is Selling Yourself?


So, awhile ago I wrote a blog post on what I personally felt being indie was. You can read the full post here: http://david.fancyfishgames.com/2012/11/what-is-indie-game-developer.html, but the basic gist was that being indie meant making the game you personally wanted to make, meaning your decisions aren't dependent on investors, bosses, even the market. While this is an interesting definition, it seems that culture of "indie" is quickly devolving into something far different.

What is the difference between a multi-million dollar AAA company, and a multi-million dollar "indie" studio? A lot of people have this idea that a AAA company is a faceless evil, and an "indie" studio is a team of hardworking developers giving their all. Does this mean that the employees of a AAA company aren't hardworking, or that AAA games are soulless? I've played many amazing AAA games that certainly were not soulless, made by passionate developers simply published through a company. Yet there seems to be shame in AAA game dev, as proof, look at the recently trending #indieAAAconfessional. Why should people be ashamed enough that they have to confess to enjoying a AAA game? What is the big difference between being "indie" and being AAA - aren't we all just game developers?

The difference (despite what most people would claim) as far as I can see it is not the amount of money or evil, but the face. An "indie" studio is transparent, you know who works there, and you know their story. This is not true with AAA games. While you can find out who actually made the game, what you typically see is the brand and the company, not the individuals. And because you can't see the faces of most of the people making AAA games, you view it as faceless, soulless, perhaps even evil. Conversely, being "indie" is becoming more and more about selling yourself and your story, with the game itself becoming secondary. Games like "Unemployment Quest" are successful because of the story of the developer behind the game, not because the game itself is any good. Look at most indie games and kickstarter projects, there is so much material on the development and the team behind the game. Most videos for kickstarter projects have a lot more footage of the developers than the game itself, even if there is a prototype and a decent amount of gameplay already.

Now, I'm not saying that all small development teams are pushing their stories, nor am I saying that it's bad to have transparency and individuality. But, I don't think the development stories should be more important than the games themselves, and I definitely don't think that selling your personal story makes you any better than AAA game companies. So, if you're belittling AAA game dev and idolizing "indie" game dev, get off your high horse and start making good games.

Sunday, February 10, 2013

Can You Escape?

First off, if you haven't played "I Can't Escape" yet, do so now, it's freely available here: http://www.newgrounds.com/portal/view/610205 . The following post will contain spoilers, and should not be read until you've played at least once.




So, at this point, you should have played "I Can't Escape." You honestly tried your best to escape, and found yourself being plunged deeper into darker and eerier levels. This part of the game is designed to psychologically invoke feelings of being trapped and helpless. Even though you had full control and nothing really jumped out at you, you probably felt scared, or a little panicked near the end. Now you wonder, is it possible to escape? You were likely never close to being able to escape, but that was probably because you accidentally fell into some pits, and maybe if you did something different, you could escape. There were even signs of hope in the game, like ladders you could climb. Now I'm going to taunt you and tell you that you can escape, and then show you this video that shows a playthrough where I escape.

Now I recommend you play again, and maybe with the information you were able to gather from the video, you'll actually be able to escape!




Still weren't able to escape? Starting to think I'm trolling you, and that my escape was a hack? Well, it was no hack, and anyone can do it, but the video makes it look a lot easier than it is. Below I'll give you a few more hints that may help you.

The first thing you need to be able to do (if you aren't able to already) is to recognize hidden pits and hidden doors. The easiest way is to see them side-by-side and notice the differences:

A normal wallA hidden door
On the left is a normal wall, and on the right is the hidden door. The cracks of the door can sometimes be hard to see, but there is more moss on the hidden door, making it greener as well.

A normal floorA hidden pit
The hidden pit is still black where the pit is, but it has green moss growing over it which makes it difficult to see. If you move carefully though, you should be able to avoid hidden pits.

By avoiding hidden pits and using hidden doors, you'll be able to explore a level much more effectively without falling. Even though most ladders are blocked off by pits or walls, in the video, I was able to break through a cracked wall by bumping into it, exposing the the ladder I used to escape.

It wont be easy, it may even seem impossible, but if you never give up, you CAN do the impossible - escape in I Can't Escape! I'll leave you with one final hint: It is no coincidence that in the video, I was on the second floor and had to climb back up to the first floor before I escaped.

Wednesday, January 30, 2013

I Can't Escape - A One Month Game Experiment

When I joined McFunkypants One Game A Month challenge, I knew that I wanted to accomplish two things:
1) To experiment with interesting game designs I wouldn't normally pursue.
2) To connect with new talented individuals.
I figured that worst case, it'd only be a month, and best case, I'd have an interesting game and know new people I could work with and trust. In this sense, "I Can't Escape" turned out to be a best case scenario!


When I designed I Can't Escape, I wanted something very simple at its core - something that could be feasibly finished in a single week! Even though the challenge gave me a whole month, it's always better to underdesign than overdesign - more can always be added, but game development almost always takes longer than you expect. Even a simple "one week" game idea might end up needing the whole month! I also chose a genre I had never explored before - I Can't Escape is my first horror and atmospheric game. It was interesting to see what I could come up with in this new territory.

At its core, I Can't Escape is exactly what it seems: you explore a creepy underground maze, stumbling around pretty much randomly without a map, and fall down pits until you reach the end. I wont say exactly what you can find in the levels, but there is no battle system, no shooting of zombies, just simple exploration with a simple goal - to escape. In order to escape, all you need to do is climb a ladder on the first level. The "horror" part is more subtle than most horror games I've played. Instead of enemies jumping out at you, there's an overwhelming sense of being watched and followed (there are literally eyes in the walls watching you - this is one of the most common events you can stumble upon). This builds the anticipation of something just around the corner, but that tension is never dispersed by having that something actually jump out at you.

Aforementioned eye staring at you deep in the dungeon.
The game is designed to make you feel lost and trapped. The levels are incredibly large and maze-like with no map to guide you. It wont take long before you have absolutely no clue where you are. The game is also designed to make you fall deeper - you're "supposed" to go up, but instead somehow you always end up going down into darker and scarier levels. With subtle effects like the movement speed slowly increasing, the anxiety rises as you realize that it's very unlikely you will even reach the first floor again, let alone escape. Eventually, you reach a level where you are trapped behind locked doors, and you literally can't escape. The light then slowly fades out, and the single word "END" appears.

The game taunts you with the possibility of escape, it even starts with you landing right in front of a ladder, with only a locked door keeping you from freedom. Along the way, you will find keys that unlock doors, and sometimes even find ladders you can climb, bringing you closer to the top. But, despite your best efforts, you still eventually fall down deeper and deeper. Sound like a metaphor for real life? Hopefully not! I won't answer whether it is possible to escape or not, as there are several rare events you can stumble upon in the game, but don't expect escaping to be easy!

A ladder on the first floor with no pit blocking it? Is it real? Did the developer just create this image as a joke??
This was an experiment for me, so I've released it for free on Newgrounds: http://www.newgrounds.com/portal/view/610205 , and I encourage everyone to try it! I also released the source code here: https://github.com/davidmaletz/CantEscape . The code is not particularly clean (lots of hacks happen with short deadlines), but if you can read it, perhaps you can answer some of the questions I've kept quiet on, and maybe even add an easy way to escape! It's too early to say how people will receive the game, and I've certainly had comments from people who didn't get it, but I've had far more comments from people who it "scared the pants right off," and that is very encouraging for me as a developer.

I really enjoyed the experience of working with Chase Bethea and Josh Goskey (this was the first time I worked with them on a project, but not the last), and I really appreciate the effort they put into the game (and of course, my lovely wife Natalie helped too)! For a one month project, I'm very impressed and proud of the work we did!

I've already moved on to my February game, so I doubt I will go back and make many changes to this game, but feel free to leave comments and let me know what you think about I Can't Escape!

Thursday, January 17, 2013

Progress Update

Here's a list of all the cool things I've been working on since my last blog post:

  • Realtime Clouds and Atmosphere - I've been working on this project for some time, it's a flexible algorithm that accurately renders and simulates dynamic & volumetric clouds and atmosphere. It's not a hack or approximation, it computes real single-scattered lighting through the clouds from a directional light source (the sun, or moon at night) and the atmosphere. It doesn't use particle effects either, it renders directly from a 3D texture, removing popping artifacts when flying through particles and making it very easy to modify and simulate. This is pretty computationally expensive, it wouldn't be possible without the power of new graphics cards - however, a few years from now, it'll probably run realtime on commodity graphics cards as well. The sunsets are especially awesome, when the sun lights high clouds from below with a reddish light, and I didn't plan or explicitly code that, it just did it since it was accurately modeling how the clouds would be lit from the sun and atmosphere!

    Right now, I've been thinking about where I want to use it, but my dream is to one day make Aero Empire with this technique. Don't get your hopes up too much if you're an AE fan, as I haven't started work on the revised AE yet and don't plan to any time soon, but I do have plans (and by the time I finish AE, the clouds might run realtime on most computers haha!).

    Of course, you have to see the clouds in motion to see the power of this technique, so here's a video:
  • I Can't Escape - As stated in my last blog post, I joined One Game A Month, and this is my January Game. I Can't Escape is a 3D, first person horror game being written in Flash's Stage3D. I have never made a horror game before, which was part of the reason I wanted to try it as my January project. The game focuses mainly on exploring a creepy dungeon with retro graphics (think old raycasting games), and the "horror" element derives from the atmosphere and a sense of being lost in an incredibly large dungeon. Most of the code for the game is done, I still need to do a few minor things, but I'm mainly waiting on art at this point as the artist I'm working with is somewhat behind. The game still needs a few more sound effects too, but the game's pretty close and there's still two weeks left, so I'm confident we'll get it done in time. You can check out the current version of the game (will continue to be updated) here: http://fancyfishgames.com/ICantEscape/ , and the game's also open source, you can view the source code here: https://github.com/davidmaletz/CantEscape.
  • Obey - Since signing up for One Game A Month, game ideas have been flooding my mind. Obey is a choose your own adventure / visual novel (with some RPG elements) that focuses mainly on the story, and the many choices you are presented with during the game. It takes place in a future dystopia, where an AI tyrant rules the world. It has multiple endings, and I've already drafted an outline for the entire game, as well as the introduction. I do want there to be some nice still art to go along with the story (and I think I know an artist who'd be good at this), but for now the main task on this game is to finish the story. Once I finish the story, I'll easily be able to make this game in a month, and so I'll schedule this game for a month after I've finished writing.
  • The Final Battle - Another One Game A Month idea, this one was spawned when reading the epic Last Battle in A Memory of Light (the last book of the Wheel of Time series, great series btw). The Final Battle will be an RTS of epic proportions, where you command armies of 10,000+ units in an all out "final battle." Every unit will have it's own little AI script, and the AI scripts will all run in parallel on the graphics card using OpenCL (I like utilizing the graphics card to do computation that would be impossible on the CPU). Each unit will also be displayed as a small, maybe 6x6 pixel sprite, which I will draw myself (it doesn't need animations or detail, so I can handle that haha).
  • Havencall - So, what about Havencall? Well, there hasn't been a lot for me to do code-wise lately on Havencall. Right now, the scenes and art take priority, which Natalie has been working on (she's been making some awesome scenes, you can see some of it here: http://www.indiedb.com/games/havencall/news/art-update1). There's still over a month of coding left for me to do in Havencall, but I plan to spread that out over the next few months, and hopefully release Havencall by September as planned. I certainly haven't forgotten about Havencall, and I'll still be able to release it on time even with One Game A Month.
That's all of the updates that I can talk about, and I have a feeling that this will be a great year for me with all my plans for One Game A Month. You can see a list of my One Game A Month plans here: http://david.fancyfishgames.com/p/one-game-month.html , which I update from time to time. Soon, the world will be flooded with awesome games made by me haha!