I am launching a new game today called Memokid. The purpose of the game is to train your memory, and it can appeal to anybody from 3 to 103 ! Here are some of the highlights of the game:
- You can choose from eight decks of cards: food, animals, transportation. One of the decks even features animated cards. Some of the decks were made thinking of young kindergarten children who need to familiarize themselves with digits and letters.
- You can have between one and four players, and if you have no partners available, the also game features an AI with 5 levels of difficulty.
- The games by default requires you to remember pairs, but you can make it much more challenging by selecting triplets or quadruplets, or easier by selecting the number of cards in the game.
- The game works on any device, including tablets and large television screens. It is available in english and in french.
From the technical point of view, the game is a departure from other development stacks I have been using. It is made entirely using ES2017 and webpack, with a full redux / react stack, and of course SVG and web-animations. I am not currently releasing the source code as I have granted exclusivity for the time being to the eveil-et-savoirs partner site, but I plan to eventually release it in open-source in a few months.
Following the release of gwt-2.8.0, I am releasing new versions of all my GWT-based libraries and applications to provide compatibility with this new release. The whole stack has been migrated to JDK8.
I am releasing a new version of lib-gwt-svg to preserve compatibility with Chrome 48+. Indeed Chrome 48+ has begun dropping compatibility with several SVG1.1 features in their quest to implement new SVG2.0 features. The sad thing is that they dropped SVG 1.1 features before they even provided a working SVG2.0 replacement !
You can get details on the removed APIs here:
SVGPathSeg interfaces (removed)
Deprecate/Remove SVGGraphicsElement.getTransformToElement (removed)
Luckily for us SVG1.1 users, I have been able to restore compatibility by leveraging the excellent polyfills developed by David Durman and Philip Rogers.
I have also noted another difference in the behavior of Chrome 48 which broke some of my HTML games. SVG elements with a width and height of 100% will not be sized correctly: they will scale to the greatest of the two dimensions and not fit into the viewport anymore. I do not think this can be addressed with a polyfill, but I was able to use the following workaround: make the SVG elements absolute and use absolute CSS positioning with width=100% and height=100% to restore the original behavior.
I would like to write in this post about problems I have had recently with my dictaphone FirefoxOS app, hoping it will help other developers avoiding the pitfalls I have fallen into. My advice falls into two categories
Think twice before you choose a FirefoxOS app type
When one wants to develop a FirefoxOS app, one first has to choose a type of application: either hosted or packaged, then submit the app to the FirefoxOS marketplace for review. A hosted app (as the name implies) is hosted on the developer own web server and can be consumed by any number of browser (FirefoxOS, Firefox desktop, Chrome, iOS…), because it is basically a classic SPA with an extra manifest file. A packaged app is hosted by the marketplace itself, and distributed as one zip file. It is specific to FirefoxOS. Packaged apps can request extra privileges (such as access to the device SD card using the Device Storage API): code reviewers at the marketplace make sure apps do not abuse these privileges.
The difference between the two types of app is well explained in MSDN, however the fact that this initial choice is crucial and has far-reaching consequences is not sufficiently emphasized. Indeed, there is no upgrade path from a hosted app to a packaged app. One cannot say: “I will start with a lightweight hosted app, add more features, and if it turns out I need more control of the device for these features, I will migrate the app to a packaged app”. This scenario is not supported. The only way out is to create a second, different app (even though the code is completely identical, except the manifest) and re-submit it as a packaged app.
Alas, this has far-reaching consequences. Developers basically loose their user base and need to start afresh, under a new app name. They need to convince users to install the new packaged app and use it instead of the original hosted one. Users of the original hosted app are stranded with data stored in that app IndexedDB. That data cannot be imported into the new packaged app.
Why is that ? It boils down to the model used by FirefoxOS to identify an app. Hosted apps are identified by the URI at which they can be downloaded, whereas packaged apps are identified by a automatically, install-time generated GUID. The OS has no notion of relationships between apps. Since it cannot for obvious security reasons let one app tap into the data generated by another one, data migration between a hosted and a packaged app is not possible (unless one uses an external server to manage export/import, which would cause all kinds of new problems).
I did not make the right choice with the dictaphone app. I started as a hosted app. A that time, I saw no need for privileged APIs because all I needed was to grab the microphone (WebAudio/MediaCapture) to capture sound and use IndexedDB to record them. Other more advanced APIs (such as the Recorder API, which appeared in FFOS2.x) had not been developed at the time. Furthermore, I saw no reason to limit the app to FirefoxOS if it could work on other browsers too, an approach which seemed encouraged at the time by MDN through articles documenting “Open Web Apps”. The app was very successful at first, because it added a feature which is useful to a lot of people. However very quickly users began rightfully to ask for a feature to export their recordings out of IndexedDB to the device SD card. Alas to access the SD card, one needs to use the Device Storage API, which is a privileged app available only to packaged apps. Ooops ! There is no way I can provide this functionality. I need to create a new app for that.
Be aware of fragmentation and stick to basic APIs
Fragmentation does not only happen in Android. It also happens to FirefoxOS devices and a lot of the early adopters are stuck with early versions of the operating system (1.0x), either because the manufacturer has not ported FirefoxOS upgrades to their device, or because the phone operator does not provide support for upgrades. The marketplace does not currently filter the apps based on the capabilities of the device or its operating system version. Therefore, developers had better have an application which can degrade gracefully for early versions of the operating system. If it turns out the core functionality of the application cannot be implemented in old FirefoxOS devices at all (as is the case with dictaphone), developers should consider whether or not to develop the app at all.
Indeed, the bulk of the users for these apps are non-technical people. They expect the thing to just work and if it does not they will blame the developer. This translates into a bad experience of angry feedback, insults and 1 star grades.
Paul Rouget from Mozilla very gently contacted me to inform me about the new Recorder API (available in FFOS2.x), suggesting I should changed the app to use it instead of my homemade WebAudio/MediaCapture codec. He is right of course (technically). However at the moment I have not found the will to do that, because I will face the following issues. Users of 1.x who are currently satisfied by the app will be pissed off because they will not be able to re-import their data in 2.x. Users of 1.x who cannot currently use the app because it requires at least 1.2 will be even more unhappy if I suggest they try 2.x instead. Users of 1.x who cannot upgrade their OS to 2.x will also be unhappy.
Following the release of gwt-2.7.0, I am releasing new versions of all my GWT-based libraries and applications to provide compatibility with this new release. The whole maven stack also receives a big overhaul, with a migration to maven 3.x and gwt-plugin-2.7.0 for building.
gwt-2.6.0 has finally been released, which is very good news. I am releasing new versions of all my GWT-based libraries and applications to provide compatibility with this new release. The whole software stack actually receives a big overhaul, and now uses JDK1.7u51 and the just released maven-gwt-plugin-2.6.0 for building.
I am launching today a new FirefoxOS app: dictaphone.js. This application implements a digital dictaphone and relies on the WebAudio and IndexedDB APIs. It fills a need of my own as I missed such an own on my own Geeksphone Peak phone and could not find something suitable on the Firefox Marketplace.
The app has its own dedicated website: http://www.fos-apps.org.
The project is completely open source and can be contributed to or reviewed on Github: http://github.com/laaglu/dictaphone.js.
The app is also distributed through the Firefox Marketplace.
The app also works on desktop browers (Firefox and Webkit-based browsers) but not on IE (which does not support the WebAudio API).
Dear lib-gwt-svg and lib-gwt-file users,
As you probably have noticed, the rate of updates and support responsiveness on the two libraries has declined in the past few months. There are two main reasons for that:
1/ It reflects the state of GWT development and Java development in general. Google has transferred the responsibility of the framework to a committee. The committee has announced bold and distant moves (GWT 2.6 in Q4-2013, followed by GWT 3.0 in H2-2014). I find some of the new directions interesting (like the focus on mobile where indeed GWT could be interesting), but until the promises materialize, I take a wait and see approach.
2/ I have pursued other interests myself, and revisited native JS development, and I really like what I found. I have ported
lib-gwt-svg to JS, and, in combination with a good IDE, it gives me the same level of comfort I had GWT / Eclipse. If you are curious, you can read more in this post.
Along with these updates, I am also upgrading my own programs based on lib-gwt-svg and lib-gwt-file: lib-gwt-chess, svgreal and lib-gwt-svg-edu. The updates mostly address Firefox compatibility issues, caused by recent changes in Firefox which broke the code. The update to lib-gwt-svg-edu is also an attempt to introduce responsive design in GWT using media queries. Depending on the format of the page (landscape or portrait) the layout of the game controls will adapt to give the greatest possible screen area to the game itself. As you can see if you look at the code, implementing something like this in GWT is far from elegant (one could do much better with native JS). I hope future GWT versions will provide a improvements to GWT CSS integration.
I am launching today two new sites dedicated to FirefoxOS applications and FirefoxOS games.
- is a web site dedicated to providing open-source FirefoxOS compatible applications.
- is a web site dedicated to providing open-source FirefoxOS compatible games.
Even though the main focus of these sites is FirefoxOS software, the apps I intend to publish on these sites are OpenWebApps, which means they will run on most modern browsers (Chrom(ium/e), Safari, IE) though some of the features may work differently on these browsers until these browsers implement the required Web APIs.
The first application available is Push puzzle.
I ported my original GWT application (lib-gwt-svg-edu-push) to pure JS and wrote a lot of code around it to turn it into a true app:
- global redesign to turn it into a web/tablet/phone friendly app
- ability to create new levels using any image (bitmap and vector)
- persistence of new levels and game state (using IndexedDB).
In the process, I had to convert lib-gwt-svg into a JS library (called libsvg.js). I wrote a separate post about the conversion process.
I hope you will enjoy this new app
I recently purchased a FirefoxOS phone and wanted to create my first application for the device. I already had a large legacy of GWT code based on lib-gwt-svg and lib-gwt-file and wondered if I would be able to reuse some of that and in what form.
I quickly realized that I would not be able to keep GWT as a framework to address FirefoxOS devices. There is no GWT plugin for FirefoxOS devices, and developing in web mode or super dev mode means several-minutes build / compile / test cycles which are just not workable for me. Furthermore, the lack of encapsulation for all the new browser APIs (IndexedDB, web activities, AppCache…) means I woudl had had to develop a GWT encapsulation layer for this before getting started.
The altenative seemed a daunting too: leaving java, Eclipse and code completion behind. I tested various JS IDEs (NetBeans, Aptana, Eclipse + JS, WebStorm) to see evaluate their code completion module.
I decided to use WebStorm as it is capable of parsing jsdoc comments to infer types of variables in a lot of cases and offers auto-completion and contextual documentation when writing code.
libsvg.js comes itself is made up of two files:
- contains the utilities part of lib-gwt-svg, as well as helper methods to help the IDE infer the proper type for JS variables method.
In libsvg.js, there are two main classes of helper methods provided.
- Factory methods
- have been added to the Document prototype to let you create SVG elements from scratch:
// Create a circle using the extra factory method added to the Document prototype.
var circle = document.createSVGCircleElement();
// Now the IDE is aware of the type of the circle variable, because it has read the prototype and javadoc of SVGCircleElement from the libsvg-ide.js file and knows createSVGCircleElement returns a SVGCircleElement. The line below is typed with autocompletion.
var circle.cx.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX, 100);
- Hinter methods
- have been added to the Element prototype to let you specify the type of elements you retrieve using calls to getElementById, XPath, DOM traversal. Technically, these methods do nothing except return the element itself, but they do it with a properly crafted jsdoc comment which the IDE can use to infer the type of the element. This presents an overhead, but it is tolerable in most cases and JS optimizers are probably capable of figuring out they are useless at runtime and eliminate the extra code altogether (though I have not verified this claim !).
var circle = document.getElementById("c1").asSVGCircleElement();
// Now the IDE is aware of the type of the circle variable, because it has read the prototype and javadoc of SVGCircleElement from the libsvg-ide.js file and knows asSVGCircleElement returns a SVGCircleElement. The line below is typed with autocompletion.
var circle.cx.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_PX, 100);