Monday, July 1, 2013
Back-drop for a play...
My friend wanted clouds, a lake, some landscape and maybe a bird and a hut, and maybe even a castle (and lots of other things I just said 'no' to.). In the end, time-pressure from work and general life-related issues allowed only the core of our initial plans to be implemented (No bird, no hut, no castle.). Thankfully the cast and crew are talented enough to make up for the short-falls on my part, and ingenious use of shadow-puppetry fills in many blanks (Or so I'm told... I haven't actually seen the play since I have to work in Johannesburg). Unfortunately, the first two shows went on without the landscape, clouds or water being properly implemented... The scene-composition tools were more important, and a deadline from work took priority. People watching the last shows might still see a hut, a bird or even a castle.
Source and instructions here: https://github.com/zskilz/scenes
Actual Demo here: http://zskilz.github.io/scenes/
At its heart, it is really a cut&paste&customise exercise using three.js example code as the source material.
Along the way I used dat.gui and tween.js to do all the tweening of dat.gui pre-sets. I also discovered how simple to use, yet effective localStorage is.
Given how little time I had to spend on this project, I'm happy to have provided something at least usable in the end.
Thursday, March 14, 2013
Guitar scales interactive.
While I'm making my way back to HTML5 game dev, I thought I'd share some work I did on musical theory.
This is a small interactive HTML5 Canvas guitar scales generator written in JavaScript. For standard guitar set-up, the Tuning Base Note should be set to "E" and the tuning to "Standard".
The scales wrap around, so the pattern doesn't often start on the BaseNote/Key/Root. It basically shows you all notes on the guitar that exist within the chosen scale.
As a exercise, guitarists familiar with bar-chords will can try find the three major chords, the three minor chords and the one diminished chord existing within the E major scale.
Guitar scales
Tuesday, March 13, 2012
Game-play concept for Rogue-Like project.
github.io page not up yet, sorry, been busy. To play download the zip and open manband.html in Chrome or FireFox (Requires webGL).
Ok, so making a fully fledged Rogue-like in three weeks was a bit unrealistic... but considering I didn't know three.js when I started, I think I did ok, though unfortunately I'm one day late on delivering something playable (on Chrome at least).
Here is what is missing, or buggy, from the game-play experience:
- EDIT: Firefox, weapon sprites not showing...
- There is a bug where the bites from small zombies are ineffectual - I know why, and I will fix later.
- Inventory management.
- The ammo indicator needs a reload display to let you know when you can shoot.
- Improved passive AI to help avoid structures.
- Flocking, for group behaviour.
- Group commands with the right click.
- A proper map with multiple arenas.
- Game events - for dialogue, death-screens, etc.
- Help screen with legend.
Next up: As a priority, I will do some bug fixes, and add any improvements to the inventory system since currently the weapon with the highest damage points gets automatically selected, which means that you need to reload and try avoid some pickups to try others. Also, a reset button is desperately needed.
After the important fixes, I suspect the pace of development will slow down since I need to spend more time on polishing my personal website, and to focus on getting possible financing so I can hopefully make games for a living...
Anyway, go check out the game-play demo here
That link again: https://github.com/zskilz/manband
Saturday, March 10, 2012
Game challenge 2 update.
I've bitten off more than I can chew and as of today, I broke the combat system, the loot system is in a primitive state, and the team artificial intelligence is, well... let's just say you can't call it intelligent.
I'm busy fixing the combat system to be more projectile friendly... If I don't get it to work I can fall back to the melee-only system whose implementation I'm not happy with. I aim to have a playable demo up on monday, but it will be the equivalent of the 1st week of the 1st project in terms of being presentable. The focus will be on core game-play concepts.
The following sacrifices will have to be made to the great deity of Keeping-timely-dead-lines:
- Player vs. world only - the AI is still too dumb.
- Loot will be kept in it's primitive fps-pickup style of functioning... and since it's single-player, no point in rushing the team loot management.
- Since the AI is dumb, you going to have zombies, because zombies are dumb... sorry.
- If any other characters appear, they'll be about as bright as the zombies.
Monday, March 5, 2012
Something completely different
So, I'm getting along with my Rogue-like project which is currently consuming most of my time. Things are looking better but the game-play isn't near the point where a public presentation is wise. The initial set of characters will be tiny and you can expect about four types of weapons and three types of armour as loot. Coins might make an appearance, but only as upkeep for your army, acting as a pacing mechanism to add urgency. The upkeep rate will also be proportional to difficulty level.
I have settled on microphysics.js to temporarily provide dynamics. I will need more time to properly research physics library options for html5 development. The options are varied and solutions that use CPU or OpenCL acceleration would be preferable.
Anyway, there's the work-in-progress screen-shot and I apologise because it isn't very pretty :
![]() |
| The brave adventurer surrounded by dogs. |
- Adapted terrain example to generate the arenas using Perlin noise. (I'd like to spend more time in a future post on this...)
- An arena can be defined with a small set of parameters, enabling random generation or defining tile-sets in a JSON file.
- Basic character class with RPG-related stats.
- microphysics.js sphere/AABB limitation limits structure placement to axis-aligned orientation only.
- Terrain dynamics will have to be faked - abstracting dynamics to spheres-on-a-plane and setting the sprite heights directly from the terrain's data.
- Character dynamics and passive AI.
- Loot management.
Till next time...
Thursday, February 23, 2012
Graphics test.
Since I haven't set up my server to properly serve the compiled JavaScript as static files yet, I'm not getting any 304 codes when serving my JavaScript files. This is a problem since the above demo relies on three.js, which takes up about 200kb (webGL+Extras)... Quite a bit to load, and I should really get the compiled files in the right place on my server so they can be loaded statically, and give a 304 if a cached version is found on the browser. This will mean only the first page load will be slow. Consequent loads will be much quicker.
It's also for this reason that I would not dare include the script references in this blog, since it would just slow down the loading of the blog way too much.
Anyway, go check out my experiment.... It shows what any Rogue-like needs... lots of character(s)! Ha ha, ha... ha.
A warning to other programmers writing graphics tests: The problem with writing graphics tests is that they can become quite hypnotic, and if you're not careful you can spend almost as much time staring at it like a mesmerized fool as you do actually implementing it...
Wednesday, February 8, 2012
Pointer Lock API means more input for your mouse.
Scheduled for release with Chrome 18, comes the much over-due, [plugin/Java-applet/NaCl]-free, ability to make games for the web with FPS style (or custom) mouse input.
Firefox has an event intercept hack to allow control of the mouse pointer. Up till now, that has been the only plugin-free way to provide FPS style mouse input for a web app. Cross-browser solutions required a Java-applet or additional plugin to "capture" your mouse input. Hardly ideal solutions. A new W3C draft proposal, the Pointer Lock API [1], hopes to standardise this issue.
The Pointer Lock API is for mouse input what what input.focus() is for keyboard input... It "Locks" your mouse pointer in place, limiting pointer movement to an area, ensuring the pointer input stays relevant and doesn't go off the edge into another window. Mouse movement values (not just co-ords, but the mouse deltas also) will be included in the mousemove event. This combined with hiding the cursor is what is required to code FPS style input (amongst many input schemes) for your app.
Since this feature is ripe for abuse, the specification demands that the user is first asked if they want to lock their mouse. The lock can be released by pressing the "Esc" key. The "Esc" key event would have to be promoted to a top-level browser event whose default action cannot be prevented.
The discussion about abuse is moot I feel. The HTML JavaScript "window" object allows you to resize and re-position a browser window arbitrarily. So whatever abuse a mouse lock feature would enable has already been enabled by the window API - remember "Rick Rolling"? (a video played a particularly annoying Rick Astley hit and any attempt to close it was prevented by the script simply moving the browser window away from your franticly flailing mouse pointer). The fact is sites that chose to exploit that feature in an abusive manner only got visited at most once. It might be good for a gag, but you can only fool them once. Also, the Pointer Lock API at least has the "Esc" hatch, making it safer than the existing window API anyway. And since the pointer can't go outside the locked area means the script can't go clicking on other windows.
Have a look at the html5Rocks article for a more technical overview [2]
Links:
[1] http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html
[2] http://updates.html5rocks.com/2012/02/Pointer-Lock-API-Brings-FPS-Games-to-the-Browser
Sunday, February 5, 2012
Game challenge complete!
Hello. Below you will find the completed game challenge. CLICK ON IT TO START THE GAME. Use left and right to move, and up to shoot. Press "Esc" or click anywhere outside the game to pause. Click the "RESTART" button to reset the game.
EDIT(2013/05/13):The Audio has been fixed. Code moved to my github account. Fire-Fox doesn't appear to automatically cache the tentacle drawing so I will still need to optimise that to increase frame-rate in Firefox. Chrome frame-rate is good.
So, I managed to achieve my goals in the allotted time, and I even managed to get it to run in a blogger page.
You might notice that the prototype post is gone. This is because I had to remove it. It wasn't written to play well with other game scripts on the same browser page (i.e. the default blog view when people visit.). It hijacked your arrow keys for the whole page, which is not acceptable web-app behaviour. This version behaves better, and pauses/mutes when you go away from it and only captures your keys after you click on it. It would be a good template for me to use to build future browser based games.*
Many features one might expect from a proper game are clearly lacking in this game. This mini-game does not provide a full-game experience, but rather is aimed as an interactive replacement for a web picture, since the whole game-code is just under 50kb non-obfuscated (not counting the libraries, of which jquery will be cached on most people's browsers, and kinetic.js which is about 40kb). All geometry and audio resources are created on-the-fly, i.e. no pictures or audio get loaded, they get temporarily generated on the client machine. It represents an experiment used to learn some new technologies, and is only the first in many (hopefully).
If you care to know some technical details and credits:I used kinetic.js library for canvas management and jquery.js library for event stuff. I ended up just using the vanilla Web Audio API implementation for Chrome build 10.0.912.77 and it gave me no hassles. In fact, I had such a blast with it I hope all browsers will have native implementations of the Web Audio API soon! If you don't have Chrome, you should just not hear any audio (sorry).
Thanks to html5canvastutorials.com.
Thanks for your interest, and please leave comments if you have questions or suggestions.
Friday, February 3, 2012
Battle of the audio APIs
Which is better? Google's Web Audio API [1] or Mozilla's Audio Data API [2][3]?
Well, actually that is not a question which can be easily answered since the two, though sharing some use-cases, are quite different. Also, to emphasise the difference, Mozilla's Audio Data API specification, officially since 15 December 2011, falls under a more general "MediaStream Processing" API specification [3]. Just browsing the two specifications will show you that they are quite different animals and that the Web Audio API specification is currently more mature (less likely to change).
To really get at the core difference between the two APIs, known that Google's Web Audio API can be,(and has been [4]) implemented in JavaScript using Mozilla's Audio Data API. So, immediately it is apparent that the Mozilla API is a lot more "low-level". That is, it gives you some core functionality which allow access to HTML "audio" elements' internal data. The specification, now more generalized for "MediaStream Processing", also allows for access to HTML "video" elements' internal data.
So, the specification championed by Robert O'Callahan and Mozilla is great for managing media assets, and performing streaming, extracting, injecting or mixing operations on raw data from audio and video elements. Microphone input would be considered a media element under this specification. The big use-case will be for in-browser video-conferencing or web-casting applications.
What is the Web Audio API then? It allows the user to build complex audio graphs, place sound sources spatially (including features like Doppler effects and HRTF ), trigger sound sources in a timely fashion, and comes with a set of pre-defined filters and effect generators. So, everything you need to make a soft-synth or a computer game's audio.
Now, since you can implement Chris Rodger's Web Audio API specification on top of the Mozilla specification in JavaScript, why have native support for it? Answer: Performance.
A JavaScript implementation of the Web Audio API, though functional, will run much slower than a native implementation. When making a game, you need processing time for game logic. You don't want CPU cycles tied up performing a set of computationally expensive convolution operations in JavaScript. Also, since the API is only a specification, a good implementation can hand off processing to hardware accelerated back-ends (e.g. on a Creative EAX card), or a browser maintained audio thread to help boost performance. For a complex scene with many filtered and spatial sound sources playing simultaneously, like in a game, you'll need all the performance you can get to keep the user experience responsive.
Also, since the audio sources in the Web Audio API are easy to fill with custom buffers, there is little reason why both specifications can't live side by side. AudioContext's MediaElementAudioSourceNode method seems like a move in the direction of inter-operability between the two specifications. The MediaStream API can manage audio streams between peer-connected clients while the Web Audio API "renders" the received data in interesting ways.
So, in conclusion, for me, there is no battle, though I personally prefer using Web Audio API since it is more geared toward the game use-case. I hope that both specifications are refined to be more complementary and get accepted and endorsed by W3C [5].
Links:
Sunday, January 22, 2012
Game rush
You control the TOSPOT (Tank Of Space Protection from Otherworldly Threats, or whatever other rude sounding anachronism I can think of before I make the game), your planet's last line of defence against the unknown dangers from outer space. The antagonists, being beings from outer space, are clearly more technologically advanced than you and their nimble frames can effortlessly evade your every attack. On their slow, meandering (yet evasive) path down to the planet surface, they shout admonitions and insult your inferior technology. The twist is that the invaders from space, although rude, are peaceful and just want to give you a group hug.
The end.
The personal aim of this project is to familiarise myself with the web audio API defined for html5 and to brush up on the html5 canvas element. This game will be 2d and I'm setting a deadline of 2 weeks for implementation. Let the challenge begin, tomorrow! (I mean, it's Sunday... you seriously expect me to start working on this on a Sunday?)
Friday, December 23, 2011
Almost done with audio
Since last post:
- Mixer. Per-source volume and pan. It can have multiple modules as sources, and forces any mono sources to fill all output channels (dependent on pan setting).
- Stk Voicer support. Can essentially make polyphonic versions of any Instrmnt and trigger it from the script environment.
- Started on Stk Filters, but apart form delay, most of them seem ill-fitted for my purposes (see below).
Currently only stereo linear-cross-fade panning is supported by the mixer module. I'll re-visit multi-channel placement later. Audio positioning for game objects will only rely on volume and pan for now.
What's still left to do?
- Ignore all Stk Generators for now... they are too low-level to merit script instantiation.. They might make a comeback as LFO-type control inputs in the future...
- Ignore most Stk filters. Filters in Stk seem to be meant as helper classes for internal workings in custom Instrmnt derived classes. Many filters do not normalize and without extreme tweaking aren't useful in an intuitive real-time modular fashion. Compromise: Script instantiated filter which can be set up as a HP,BP,LP or BS filter. Internally an IIR Stk filter can be used with a known calculated set of normalized coefficients for Butterworth filters. This will be sufficient for games.
- Ignore score files for now... The effort which will have to go into creating a scoring environment is beyond the scope of a gaming project. It is a love of mine, hence the long interlope. I will come back to this, but not yet.
- Ogg file loading/playback for music needs to happen (Easier to compose music in Renoise for now).
- Stk Effects to support : Chorus, JC-Rev, Echo ... the rest can come later.
- Implement tying motion-states to audio sources.
Tuesday, December 20, 2011
No pretty pictures here, please move along...
Disclaimer: programmers only.
It has been almost a month since the last post and no "visible" progress has been made...
Lots of code have been committed for the purpose of making a couple of extra lines of script work.
Basically, I had to write an interface class for an abstract "sound module"... which is something with an internal audio buffer and references to inputs and outputs to other sound modules. Script interfaces had to be written for connecting modules together with logic to detect any feedback between modules. The only sub-classed objects so far is a master module, which abstracts the "default" audio output device, and a Stk Instrmnt wrapper class.
When I designed for using Stk, I planned around the Stk base interface classes as much as possible, and being obsessed with the sound module idea I settled for the most common audio processing virtual function shared by all higher level Stk interface classes... namely : StkFrames &tick(StkFrames&frames).
Since this most common tick function processes a block of audio frames, I thought it best to have the algorithm which processes the audio frames in as large a chunk as "real-time" permits... Stk defaults to 512 frames, which at 44k1Hz equates to about 11ms (good enough for games!).
Wasting of time, feeling stupid and doing more work than necessary happened when I decided to design for feedback support after already having "chunk" optimizations in place.
What am I talking about? Say you have an instrument which you plug into a mixer. That mixer goes through an EQ and into a splitter. That splitter then has an output to a chorus effect and another to a re-verb effect. The chorus goes to the master output, but the re-verb goes back to the mixer the instrument is plugged into. Why do you want to do this? Well, why not? It might sound cool... who knows, but the point is you might just NEED it somewhere.
The problem is now apparent since it is clear that the mixer's second input is dependent on the output of some later stage which is in turn dependent on the mixer's output. The best you can hope for in a digital system is to allow the mixer to do a single frame's tick, propagate that tick though all modules until you update the module the mixer input is dependent upon which will then serve as the input to the mixer's next single-frame tick operation.
So, if like me, you went ahead optimizing for chunks, and then wanted to go and have a special feed-back case which just does single ticks, then you're probably also half-wasting your time (I'm sure it's possible, just probably not with the way I went about it.).
What I kept from this misadventure was just the ability to detect if there is feedback when a connection is created, and throw a script exception if so, not allowing the connection. A lot can be done still with just feed-forward modular audio networks, so apart from the wasted time, I'm not too bumbed.
So, I now have the master module which is the entry point for connection to other modules and the Stk Instrmnt wrapper (which currently supports all the sub-classed instruments Stk has to offer). Further sub-classed modules still need to be added to complete the whole sound experience, but the minimals are coming together nicely.
The basic functioning of the audio engine is like:
- audio callback requests buffer
- audio engine processes the master module
- master module processes its source modules recursively
Friday, November 25, 2011
What went wrong this time? (Adventures with STK)
I've made the first steps for physics, interaction and graphics, and since I'm interested in making desktop games, it is only natural to do audio at some point...
I thought it would be easy to integrate Qt's audio functionality when using the qmake tool-chain... add qtmultimedia to the config in your .pro file, and include a QAudioOutput class somewhere and trigger sounds from that... Right?
Well, it kinda is... but not really... QAudioOutput is a reasonably low-level interface class and can read from a custom QIODevice derived class (pull mode, good for streaming... limited real-time application) or you are provided with a QIODevice which you can write to once a notify interval has elapsed (push mode... more real-time). A QIODevice "talks" in raw bytes... so either way you still need to take care of formatting your audio data correctly to match the stream parameters (code for this can be seen in the Generator::generateData method in the Audio Output Qt example ). Also, no mixing/routing functionality is provided... you're expected to implement that or use some third party library like STK. So, although the QAudioOutput class provides a solid cross-platform starting-point, it still requires you to implement a lot of the low-level, broiler-plate, byte-array, endian-conscious code. Also, this part of the Qt framework is under active development so it might drastically change in the main Qt distribution as projects become merged into it. It is inevitable that technology will pass you by... but it is all part of the learning process.
For a while I've wanted to use Perry Cook & Garry Scavone's STK (https://ccrma.stanford.edu/software/stk/) to provide the basis for a soft-synth audio framework for my game engine. As a preference I decided on RtAudio and STK over PortAudio and CSound, though I know much is interchangeable and CSound has a great deal more features. I was drawn in bySTK's well balanced compromise between latency (#1 consideration for games), footprint and readability.
The aim was to have an audio engine class which gets instantiated along with the script environment, which would also provide script interfaces into a range of STK classes and to dynamically connect them in a modular fashion... Since STK can be compiled without RtAudio dependence I though it best to stick with the QtMultimedia module since I was relying heavily on Qt already.
One can conceivably tie STK's non-real-time build in with a push mode implementation involving QtAudioOutput, but, after wasting much time, in the end experimentation with RtAudio made me decide to use it instead of QtAudioOutput. The biggest factor for me was that RtAudio already deals with floating point samples and transparently does the conversion to raw audio for a wide range of audio formats. Also, it has a relaxed open source license and is cross-platform (Linux/Mac/Win). My DSP courses dealt mostly with audio signals represented as numbers in the range -1.0 to 1.0, so RtAudio is a more intuitive fit in this regard also.
On the plus side, choosing RtAudio over QtMultimedia also provided the additional ASIO support in windows ( although ASIO support is compiled and tested, I'm defaulting to dSound on Win32 platforms for now) and RtMidi cross platform MIDI IO support ( which has also been compiled in but is waiting untapped). The STK source files have been statically incorporated into my project not because I planed it, but because I was initially only using some elements of STK... Eventually all of STK source got included. I might eventually move back to just linking to the STK library. Right now I don't care much because the code footprint is small and all the STK classes are pre-compilable, so they don't affect consequent compile times much (exception is lesson 1).
Lessons learned:
- Complacency can make you forget the classics: Changed a define in your project file? CLEAN! REBUILD! (And don't forget the cleaning part. Too embarrassed to say how much time I wasted dealing with puzzling bugs after forgetting to do this).
- RtAudio's closeStream() method should never be called from a destructor of a class your RtAudio instance is part of... safer to have a pointer to a RtAudio instance which you manually delete after step 3.
- You need the "bool done" tick-data element you see in all the STK code examples... no escaping it if using the tick() callback functionality. In the main tick() callback check for data.done and return -1 if it is true; The audio engine class destructor should set the "data.done" value to true and should sleep for a couple of microseconds to allow any pending callbacks to return a -1... only then is it safe to delete the RtAudio instance without a hang (on my system at least).
- Building STK with Qt(Qt Creator/qmake) MINGW: If like me, you added all the stk/include and stk/src files to your Qt project, you'll need to add some defines and library dependencies to your .pro file to get everything linking and compiling right. To get the compiler setting and project defines for STK, run STK's configure script from within a msys shell to generate a makefile. Reading this makefile will tell you what defines and libraries you need to add to your Qt .pro file (you can also look at the VC project files that come with STK but it is more verbose and the linker syntax is different).
Not much really, just getting everything compiled together and first steps of simple integration for now. Tones are generating; instruments are playing; filters are filtering; effects are effecting even... but only C++ tests hacked into the audio engine's initAudio() method for the interim. The initial tests show promise. No audio script interfaces or script definable modular flow graphs have been implemented yet... that is next.
I still have a lot to do with the sound-programming before my next update... sorry, I know I can ramble sometimes. This post went on for longer than intended.
Useful links:
- http://www.mingw.org/ (msys doesn't come with Qt Creator installer)
- https://ccrma.stanford.edu/software/stk/ (STK Home page)
- http://www.music.mcgill.ca/~gary/rtaudio/ (RtAudio Home)
- http://web.mit.edu/carrien/Public/speechlab/marc_code/ADAPT_VC/rtaudio/doc/html/ (MIT RtAudio Tutorial)
- http://www.music.mcgill.ca/~gary/rtmidi/ (RtMidi Home)
Thursday, November 10, 2011
What have I been doing so far:
The video shows the summary of my progress on my ECMA-based 3d engine called "ThingMaker" (for now).
It is not impressive to look at for some reasons. You're seeing a early-stage, work-in-progress debug-render of a series of tests, so there is no attempt at aesthetic appeal... The screen recorder program slowed the frame-rate down considerably... I had to compress it a lot cos my up-speed is very slow... This site's video up-loader compressed it even more... So, that's why it is so ugly.
The video starts with the engine initialized. Next I run the test script. Everything in the video is dynamically created via the script environment. There are some script-defined geometries(floating shapes), some physics objects drawn in lines(the pool table), and physics shapes with dynamically created geometries(the reddish shapes with lines around them).
The tools used to create what you see: Qt framework, Bullet Physics.
Behind the scenes:
- Script binding of basics of the Bullet API (no soft-body or constraint support yet, and only basic convex collision shapes supported).
- Script binding of OpenGL 3.3 geometries and shaders.
- Script definable collision callbacks.
- C++ interface for physical controllers, or they can be defined in script.
Wednesday, November 9, 2011
Welcome back.


