I'm not sure if you've yet noticed, but I've been very into making browser games recently. I think the web is an exciting platform with a lot of cool things you can do. From Binaural Audio to doing things with sensors like Gyroscope and Accelerometer and other cool things, as well as the fact that they run virtually everywhere a modern web browser does, the web has it all and I thought it was time we started experimenting with this.

I already wrote a couple of games using these web technologies, the most known is probably Cyclepath. It uses sensors to help with turning on mobile, snappy Keyboard Input, as well as binaural Audio with environmental effects, basically everything an audio game would need.

I wanted to give to the community, so I've spent the last few days decoupling all these snippets of code and making them completely reusable by anyone. Furthermore, they're all on GitHub, so anyone with the knowledge of JavaScript can help me improve them and end up in the published module on NPM. I'd be very happy.

For those of you that already know how to develop using modern ES6 JavaScript and don't want to read about how to set up a testing and development environment because you already know how, all these modules are on GitHub and NPM.

My GitHub profile: https://www.github.com/ghorthalon/
My NPM profile: https://www.npmjs.com/~ghorthalon

The libraries you will find there:
AGK-Input: Helps with Keyboard Input, and let's you use the Keyboard somewhat like you were used to from BGT in the browser.
AGK-SoundObject: An easy way to load, preload and play sounds.
AGK-SoundSource: Quick wrapper around AGK-SoundObject, which is a wrapper itself so this is a total WrapperCeption, to quickly create 3D sound sources.
AGK-TTS: Quick way to speak in the browser
AGK-UI: Build simple user interfaces like Menu's and scrolling text
AGK-Utils: Random stuff like distance, collision, random numbers, stuff that hasn't yet made it into it's own module but will at some point.

Examples and usage is on the respective GitHub or NPM pages.

If you don't know how to set any of this up then don't worry. I'll work on sharing my development template or boilerplate code including all my scripts to build and test games and quickly get to production. This is going to take me some time though, so please be patient with me.

I'll also be working on an example game that utilizes all of these libraries and is easy to understand.

But a quick introduction

I use the parcel bundlers to bundle my code. This is more or less necessary to make use of modern ES6 modules properly. If you want to quickly set up an environment:

Install Node.JS. You can get Node.JS from www.nodejs.org.
Create a directory for your game.
Open a terminal and enter your game directory.
Type npm init
Fill out the fields to your liking.
Once it has written the package.json file, install the modules.
The ones you'll need globally are:
npm install parcel-bundler -g
npm install http-server -g

The -g tells it to install these modules globally. That means they'll run everywhere in your terminal as well as be globally available in your JavaScripts.
Time to install the modules for the game.
Make sure you're still in the directory of your game. For now, we're going to only write a quick script that uses AGK-SoundObject to play a sound. Then:
npm install agk-soundsource --save

The --save tells NPM to update the dependencies in your package.json. This is useful for when you share your code. If a package.json is present in the current directory, simply typing npm install will install all the dependencies present in your package.json file.

OK, we have the module. I usually set up a client directory for all my HTML, sounds and javaScript.

mkdir client

Cool. Go into that directory and create an index.html, a js folder and a sounds folder.
Drop any wave file you want in that sounds folder. It doesn't need to be just wave files, you'll have to look at your browser and what codecs it supports.

Sweet. In the js folder, create a file called main.js.

Populate the file with this contents:

import SoundObject from "agk-soundobject";
SoundObject.directory = "./sounds/";
SoundObject.extension = ".wav";
const sound = SoundObject.create("meow");

This will load the meow.wav from the sounds folder in your client folder and play it.
Right. Next open index.html outside of the JS folder and populate it with this:

<title>My game yay!</title>
<script src="./main.js"></script>

The main.js file will be created by parcel in the next step in the client folder, not inside the js folder. The JS folder contains your written code, the main.js file outside of the JS folder will be the compiled JavaScript.

Open a terminal and make sure you're inside the client directory of your game.
Then run this:
parcel watch ./js/main.js -d ./ --target=browser

Parcel has a few commands. Watch will open a server that constantly looks for changes in your JavaScript, and when a change is detected it will automagically rebuild the bundle. Furthermore, if your browser tab is currently open the browser will automagically reload the changes you've made. Awesome right?

Next, open a new terminal and get back into your game directory. Then simply run:
http-server ./client

This will open an HTTP-Server to your client folder.
Now you can open your browser and go to http://localhost:8080 and if everything goes as planned you should hear meow.wav!

If you didn't understand any of this, then that means you've not messed much with modern JavaScript. That's OK. There are so many resources to learn javaScript development out there it's unreal. Just go wild and don't be afraid to mess around.

If this seems counter productive and like a lot of work, yeah you'd be right. It used to be much more convoluted when we didn't have Parcel and had to configure webpack by hand to build the files, luckily parcel exists now and that step falls away.
That said, I'll soon upload my development template, so you will just be able to clone it with git, npm install and start coding right away.

If you have any questions feel free to ask.

I hope I didn't miss anything and I hope this is of use to someone. Have fun! <3

Wanna play my Games? Listen to my Music? Follow me on Twitter, and say hi~
Code is poetry.

Thumbs up +7


ok ghort, this is definitedly awesome. you did a small framework for build games in JS, using your favorite tools and libs. keep doing that amazing work.
Waiting for the voilerplate for a complete project!

Thumbs up


Doing things in the web is good, but I do want a fake desktop app, that is to say, Electron. Reason I say fake is because in actuality it's a web app bundled to look like a desktop app, from how I understand.


Thumbs up


The easiest way to build an Electron app out of your web app is to change into the directory of your game, the main directory. Then type:
npm install --save-dev electron
--save--dev saves Electron in the development dependencies of the project. These are only installed when you're on your development machine. Open package.json, find the scripts section and add a comma after the one that's already there, then add:
"start": "electron ./client"

Save the file. now, when you run
npm start
Electron will open with your game.
To build your electron app into executables for all platforms, install electron-builder into your global modules like so:
npm install electron-builder -g

Then, in your main directory of the game, type:

It will build for all major systems. Mac, Windows and Linux. Code signing will only work if you're on Mac and have a developer account, however it is possible to build for Mac, windows and linux on one platform. Cyclepath was built for all systems on Windows, so you don't need mac to write Mac applications, however only Mac can create DMG files so you will have to distribute your Mac applications as zip files if you're developing on Windows.
That said Mac has quickly become my favorite development platform. LOL

Wanna play my Games? Listen to my Music? Follow me on Twitter, and say hi~
Code is poetry.

Thumbs up


What do you use on Mac to develop? How is it better than Windows?
I'm on Mac, however I hate VoiceOver on the web because when viewing tutorials, VoiceOver reads code all on one line, and it's hard to view it even when interacting with it.


Thumbs up


If you turn quicknav off and arrow up and down on the page, the code will read properly.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

Thumbs up


I never have quicknav on. I'll try that again but last I tried it was acting odd.


Thumbs up


That only works in Safari, as far as I know Chrome struggles with that. I just like the unix shell and CodeRunner/TextMate make forget code editors. I also figured out how to make VS Code read properly, and that gives you easy access to consoles with breakpoints etc. This also works on Windows though. And other than that it's mainly the laptop. The MacBook Air is great for portability and especially battery life. There's more obviously, but yeah I guess that could warrant it's own topic.

Wanna play my Games? Listen to my Music? Follow me on Twitter, and say hi~
Code is poetry.

Thumbs up


Does CodeRunner do pretty much the same things as TextMate? CodeRunner I like for it's IDE code completion stuff, but would there be a reason to have TextMate as well in the toolbox?


Thumbs up


Awesome! Thanks so much for this! I have two questions:
1. In the libraries you provided, are there functions to read raw binary sound data? I ask because people could potentially make sound packaging formats. Many benefits to this, one of which allows for encrypted .dat files, or custom formats. I assume NPM has modules for compression, etc? I don't know, I haven't messed much with NodeJS. smile I'm so used to C/C++.
2. If not too much to ask, how did you learn about all of this? Just a quick summary would suffice. I suppose that an answer to any such question could be something as simple as, "I learned it through experimentation and article reading." smile But if anything else helped, I'd like to know about it.

Thanks again.

Click here to friend me on Facebook.
Click here to follow me on twitter.
If you want to add me to Skype, my name is lozano.edgar.
Please let me know that your from the AudioGames community if you wish to add me on any of these sites.

Thumbs up +1


How I made js audio games back in the days of IE6:

Usually, the script for the game was in the html file, so as to have easy access to named elements. I offloaded the "getElementByX" crap to functions as much as possible.
I kept an ever-expanding script file with seemingly useful stuff. Somehow, I mostly only used my workaround for the array length issue (it seems like that's been solved since?), cookies, changing the contents of divs, and moving images.
So an example might look like:

<title>Demo Game</title>
<script src="specialFile.js" type="text/javascript">
<!— sound was only really available through embed objects: —>
<embed name="mysound" src="mysound.wav" autostart=false hidden=true loop=false mastersound>
<body onkeydown="keyPressed(window.event.keyCode)" onkeyup="keyReleased(window.event.keyCodegg">
<div id="textlayer">Press any key to begin?</div>
<script language="javascript" type="text/javascript">
<!— Hide the script from ancient browsers...
function keyPressed (k) {
if (!k) k=window.event.keyCode;
if (k==65) document.mysound.play();
else if (k==90) WriteLayer("textlayer", "You pressed z, right?");

function keyReleased(k) {
if (!k) k=window.event.keyCode;
if (k==65) WriteLayer("textlayer", "Wasn't that fun?");
else if (k==87) document.mysound.stop();
// end hide —>

I might have made some mistake in there, but that's the idea I understand that window.event is deprecated and all the many tutorials telling me to use it should have gone with, like, document.event or something instead. Also, people have decided to drop the hiding, since the internet is gated now or something and who uses Netscape anymore, anyway? And apparently audio is ... is audio easier now? Because I had balance, volume, and rate available through embeds, so 2d sound was trivial. I understand we have 3D now (for whatever that's worth in a world without 3d audiogames), and that <embed> has to preload everything and that takes forever and clashes with post-IE6 security things. But how you do audio seems to be different every year and requires all of this additional setup, and I am lost and slow to trust anymore.
Oh, and I left out timeouts. For some reason the setTimeout function always made me nervous, not that I didn't use it.

So, my main question: after doing everything in the OP, installing this that and the other, typing 5 CLI commands, and setting up one of those hidious standardized project directory trees, how complicated are handling events, playing sound, and dealing with HTML elements? Will it work? Because if I follow the steps as given and cannot get these things to happen with comparable ease after 3 tries, I give up entirely and resign myself to being the annoying old person whose response to everything is "back in my favorite decade..."

Some of my games
Keep up to date by following @Jeqofire on twitter!
Ear Ninja?

Thumbs up


Haha Cae. smile

It really depends. My answer would probably always be NPM. Events are super easy to handle and do with something like event-emitter3, or the normal javascript event listeners through the event API. WebAudio is basically OpenAL in the browser, and you have things like webBluetooth and other webSensors like accelerometer and gyroscope, etc.

The thing you don't need to worry about is something breaking. We're at a point where we can only move forward and add, not remove. If something gets removed then there was a significant problem with it and there are huge security reasons not to do such anymore.

You do not need to go through the complicated way of setting up a web project like I have. You can just go out and grab your favorite libraries as .js files and write your scripts like you always have. The reason I do not is because NPM is huge. If I need physics I go on google and search for physics npm.
Let's say I find bullet.js. It has a convenient NPM page, I quickly read up on the API, then switch back to my terminal and do npm I bullet.js --save and I can start using it right away. When something get's updated in libraries later I simply npm update, and it makes sure to not pull in any code breaking changes while updating at least minor versions and patches.

I also like the OOP way of programming since I come from Java, or at least that's what work made me use. Writing code in the way I do let's me use classes and inheritance like you were kind of used to from Java.

class MyObject {
    constructor(someParameter) {
        this.parameter = someParameter;
    someMethod() {
        console.log("Do something in here");

class AnotherObject extends MyObject {
    constructor(anotherParameter) {
        this.anotherMember = "Meow";
    anotherMethod() {
        console.log("Both functions are now accessible on the object yay");

const object = new AnotherObject();

This is epic I'd say.

Another reason I do it like this is to use imports. Say I want to have those two classes in one file and export them to be able to be used in another file.

I simply add export { MyObject, AnotherObject};
Or, if I just have one object,
export default MyObject;

Now, in any script I need this function in, I can import it using either
import { MyObject, AnotherObject} from "./myFile.js";
or, if there's only one...
import CustomName from "./myFile.js";

This way, everything is kept within it's own scope and you don't clutter up your main scope with things. So things that aren't supposed to read other things won't be able to read those other things. Makes your code a bit more secure and safer to write.

Also there's const for constants now, and let to instantiate variables within the scope. Var was never sure where it'd end up, and usually it was either the entire function or even just globally. Now you can bind your variables to whatever you wanted them to be.

I know it sounds super confusing but if you give it a chance it's super powerful. A lot is happening there, we already have our new JavaScript for this year with a lot of cool things for templating and promises, and promises are especially cool for working with asynchronous code and avoiding tons of callbacks, but maybe I'm rambling on here.

Your old code probably still works today. Just... please... Let IE6 die in peace. It's endured too much already and it's time for it to rest and not come back tongue

Oh and I totally forgot to answer where I learn. You're just about right. Reading tons of articles, tons of just messing about, but I also think that there are a lot of really good talks about node.js, JavaScript in the browser and how to code modern JavaScript on YouTube. And, you know, just asking around.

NPM is great though. Literally anything you could ever want is up there. Over 800 thousand packages. No matter what you're looking for someone probably already wrote it. You just pull it in and it manages all your dependencies for you. Of course there's some dangers with that, like broken or unuqdated or unoptimized packages, but really you would get that just as much if you were copy/pasting from Stack Overflow tongue just look at how often it gets updated and what people are saying and you should be fine. I never had problems so far.

God what a messy post. I better send this off before I get too caught up in myself...  LOL

Wanna play my Games? Listen to my Music? Follow me on Twitter, and say hi~
Code is poetry.

Thumbs up +1


Hi, does anybody know how to solve this problem? Whenever i type the parcel command and start up the http server, i go and edit my main.js to make a change and it doesn't reload. After restarting parcel and http server it still won't see the change.
If anybody can help with this I'd really appreciate it.

Thumbs up


I'm so glad someone else is using JavaScript.

Of course my main focus is in the web (especially now I have me a ChromeBook), but looking at that electron stuff looks awesome.

I keep promising myself that next time I write something server-shaped I'll use node.js, but it's not happened yet... mainly because I'm so damn used to Python.

Loving coding in the browser though... My only bitch is that there's no simple way (that I have found) to insert random numbers after the script src so that the web page doesn't use its cached version.

With mindspace I use the last modified timestamp of the client.js file but that seems stupid dirty.

Anyways, bring it on, the web is awesome and being able to play games on phones and basically anywhere else (minus them stupid blind-specific devices which should be scrapped anyhow) is seriously cool.

Take it easy.

Take care,
Chris Norman
Selling my soul to andertons.co.uk since 2012.

Thumbs up