投稿されたすべてのトピック

Servo で WebVR できるまで (その1)

["WebVR Coming to Servo: Part 1" の抄訳です]

VR はウェブで普通に使えるようになるべきです。そのためには、私たちの考える未来を実装するための柔軟で高速な処理系が必要です。 Servo はモダンで、ハイパフォーマンスなブラウザエンジンです。 アプリケーションとしての用途はもちろん、組み込み用途でも利用できるように設計されており、 Mozilla が 1 から実装を行なっています。 その技術的な目標とプロジェクトを取り巻くコミュニティと文化に共感したため、 Gecko (Firefox) への実装に並行して、WebVR を Servo に実装することを決めました。

Imanol Fernandez が WebVR API を初めて Rust で実装しました。 彼の実装である rust-webvr はブラウザーから独立していたため、単体でテストや利用ができました。 例えば Rust で実装された OpenGL アプリケーションが、 ブラウザーで利用できる API と同じものを使って VR ヘッドセットをコントロールできるようになります。 その次の目標は、Servo のアーキテクチャとの統合です。そのために、私たちはスクリーンに何かを表示するところから始めました。

Linux と Mac OS X では、Valve と Oculus の提供する SDK を利用できません。 そのため現在デスクトップ向け VR は Windows でしか動作しないものとなっています。 3D コンテンツをスクリーンに表示するために、Imanol は Servo に Windows 向けの WebGL バックエンドの実装を開始しました。 単純に考えて、WGL から始めることとしました。これは他のコンポーネントによって、すでに利用されていたためです。 将来的には Angle を利用したバックエンドの提供も考えています。 これはそれぞれの GPU のパフォーマンスをもっとも引き出せる選択肢となるでしょう。 VR アプリケーションにとって、低い遅延と高いフレームレートは必須の要件です。そのためには、JavaScript で WebGL の関数を読んでからスクリーンにピクセルが表示される前での間に、 何が起きているのかをしっかりと把握しなくてはなりません。 WebGL 関数の呼び出しには、Servo 内の異なるパーツが関係しています:

Servo 内の WebGL 関連モジュール

JavaScript の評価器と、IDL バインディング

Servo は JavaScript の処理系として moz-js を利用しています。これは SpiderMonkey の派生物です。 V8JavaScriptCore と同様、moz-js は JS の評価器としての機能しか持っていません。 WebGL のような API を追加するには、JS からネイティブのクラスや関数へアクセスできるようにする必要があります。 これは仮想マシン (VM) が提供する C/C++ の API を利用して実装されます。 その結果、JS のクラスを定義し、ネイティブと JS の関数を相互に呼び出すことが可能になります。   API を追加するためには、引数のチェックや JS – C++ 間のデータのやりとりなど、 似たようなコードをたくさん書かなくてはなりません。 これに加えて Servo では、C/C++ と Rust の間のバイディングコードも書かなくてはなりません。 このコードは rust-bindgen というツールを使って WebIDL と呼ばれる言語非依存な API 仕様から自動生成されます。 このツールのおかげで API のロジックに集中することができます。

Servo で API を定義する IDL はこちらで公開されています。これには WebGL も含まれます。

WebGL に関連する DOM オブジェクトの 実装

WebIDL バイディングによって Rust と JavaScript を繋げるためのコードは、自動的に生成されました。 その次は、個別の関数やクラスの実装です。実装がないとコンパイルができません。 そのため DOM オブジェクトである WebGLRenderingContext も実装しなくてはなりません。 こちらにその実装があります。 WebGLProgramWebGLShader のような、その他の WebGL クラスの実装も同様です。

これらの DOM オブジェクトは WebGL オブジェクトの状態を表していて、検証のためのルールは全て WebGL の仕様に定められています。 ただし、レンダリングコマンドの処理は全て、WebGL スレッドという別のコンポーネントへ委譲されます。

WebGL スレッド

Servo は並列処理アーキテクチャを取っています。そのため他のコンポーネント同様、WebGL のレンダリングコマンドは他の DOM の描画処理を行うスレッドや JS の評価を行うスレッドとは独立して実行されます。 これはパフォーマンスの向上には好都合でした。なぜなら GL の GPU ドライバーに対する呼び出しが JS の実行をブロックしないためです。 ただし glReadPixelsglGetParameter のような関数をを呼び出した場合は例外です。 これらの関数を呼び出した場合、JS スレッドは WebGL スレッドからのレスポンスを待つためブロックされます。 それでも十分に最適化されてた WebGL アプリにとっては問題にはなりません。

Servo の WebGL スレッドは DOM からの WebGL メッセージを受け取り、処理するように実装されています。 今の所、2つの描画パスを利用できます。どちらを利用するかは Servo の初期化方法によって決まります:

  • Webrender: WebGL スレッドは GL 関数呼び出しを Webrenderer コンポジタースレッドへ送出します。最近 Servo の標準の描画パスとなりました
  • rust-zure: 描画の抽象化レイヤーです。以前は標準の描画パスでした。グラフィックススライブラリーである Skia を内部的に利用し、スレッド内で GL 関数の処理を行います

Webrender は最適化された WebGL の描画パスを持っています。 それは 共有の OpenGL テクスチャを使ってコンポジションを行います。 一方 Skia は readPixels を用いてテクスチャを共有するため、その WebGL 描画パスは最適化されていません。

Servo と Rust のプロセス間通信

WebGL DOM は GL 描画メッセージを異なるスレッドを送出します。 Rust の標準ライブラリではスレッド間の通信には非同期のチャンネルを利用しますが、 Servo はマルチプロセス処理を向上させるため、独自に実装した ipc チャンネルを利用します。

チャンネルと Rust の強力な列挙型を組み合わせることにより、プロセス間通信はエレガントに実装できました。 WebGL スレッドで利用される WebGL コマンドは全て webnrenderer_traits に実装されています。 このコンポーネントは WebRender と Servo で共有されています。

OpenGL の呼び出し

Webrender チャンネルは GL コマンドを受け取り、OpenGL の関数を呼び出します。 ただし、この設計は将来変更されるかもしれません。その理由は GL コマンドのバッファリング機構の実装が計画されているためです。 Webrender は 1 つの GPU プロセスで、全ての WebGL コンテキストの処理を行います。

実際に GL コールを行う前にやらなければならないことがあります。 それはプラットフォームごとに異なる実際の関数の呼び出しです。 OpenGL ドライバーを呼ぶことになるかもしれませんし、 DirectX バックエンドを利用するために Angle のような OpenGL ラッパーを呼ぶことになるかもしれません。 もしくは OSMesa を利用するかもしれません。 Windows のようなプラットフォームでは、異なる OpenGL 実装を DLL として実行時にロードすることさえ可能です。 その DLL は OS によって提供されたものかもしれませんし、GPU ドライバー由来の最適化されたものかもしれません。

これらのラッパーを動かすためには、OpenGL のシンボルを動的にロードしなくてはなりません。 Servo は gleam ライブラリを利用して、同じ OpenGL シンボルを全てのコンポーネントで共有しています。 gleam は内部的に gl_generator を利用します。これは Rust コミュニティではよく使われるユーティリティで、 OpenGL の関数ポインターのローダーとバインディング機能を提供します。

これでついに OpenGL の関数呼び出しがドライバーまで到達しました。

Servo のコンポジションにおける WebGL アクセラレーション

これまで WebIDL のバインディング、DOM の実装、WebGL コマンドのマルチスレッド化、そして実際の GL 呼び出しについて述べてきました。 ここでは、WebGL canvas がメインウィンドウの描画コンテキストへ、どのように組み合わされるかを説明します。

Servo はメインウィンドウを GLutin を利用して作成します。 これはクロスプラットフォームウィンドウやメインの描画コンテキストの作成を助け、 入力やイベントの受付を簡単にするライブラリです。

WebGL コンテキストはヘッドレスなオフスクリーンコンテキストとして実装されています。 GL コマンドは テクスチャアタッチメントされた FBO を用いてテクスチャへの描画を行います。 WebGL の描画コマンドはマルチプラットフォームなものですが、ヘッドレスの GL コンテキスト作成はそうではありません。 プラットフォーム間の差異を隠蔽するために、Servo は rust-offscreen-rendering-context を利用します。 このライブラリは、ヘッドレスコンテキストの作成を抽象化し、EGL、CGL、WGL、OSMesa といった多様な API をサポートします。

Servo のコンポジターは Web ページの全ての要素の描画を管理するコンポーネントで、 GPU レンダリングには Webrenderer を利用しています。 WebGLContext は独自の描画コンテキストを持ちますが、コンポジターレイヤーとも描画コンテキスト共有されています。 共有が効率的に行えるのは、共有されたテクスチャのおかげです。

ウェブが飛躍的に進化します

この投稿は米国 Mozilla Tech Blog の記事 “A Quantum Leap for the Web” の抄訳です。

ここ 1 年間の Firefox にとっての最優先事項は、ブラウザのマルチプロセス化を行う Electrolysis プロジェクトでした。 Firefox を複数プロセスに分割し、セキュリティとパフォーマンスを大きく向上させる、このプロジェクトは Firefox 史上最大の改良となりました。その成果は、これから数ヶ月をかけて、すべての Firefox ユーザーに提供される予定です。

しかし、このプロジェクトが Firefox 最後のセキュリティとパフォーマンス向上となるわけではありません。むしろ、 このプロジェクトによって Mozilla の次なる大きなプロジェクトの準備が整ったのです。

Quantumは次世代型ウェブエンジンを開発する取り組みです。 2017 年末にはその成果を届けられる見込みです。ウェブエンジンとはブラウザの核です。つまり、読み込んだコンテンツの実行と、描画を行うブラウザ内のパーツのことを、ブラウザエンジンと呼びます。 Quantum では並列処理を採用し、最新ハードウェアの性能を最大限活用します。 Quantumはいくつものコンポーネントからなりますが、その中には Servo プロジェクトから継承したものも含まれていまます。

これによって完成するエンジンは、モバイルとデスクトップ OS の両方において実行速度の高速化となめらかなユーザーエクスペリエンスをもたらし、パフォーマンスが飛躍的に向上するでしょう。このパフォーマンスの改良はとても著しく、ウェブ体験そのものが違ったものに感じられるほどでしょう。ページの読み込み速度は向上し、スクローリングもよりなめらかになります。アニメーションやインタラクティブアプリのレスポンスも瞬時に感じられ、フレームレートを一定に保ちながらより高度なコンテンツを処理することが可能になります。そして、ユーザーにとって重要なコンテンツが自動的に優先され、そこに処理能力が大きく配分されるようにもなっています。

これは、どのようにして可能になるのでしょうか。

ウェブブラウザは、デスクトップ PC の時代に登場しました。この時代のコンピューターにはコアを 1 つしか持たない CPU が搭載されていたため、同時に 1 つの処理しかできませんでした。今日においても、多くのブラウザはウェブページを 1 つのコア上で直列的に処理しています。

しかし時代は変わりました。スマートフォン、タブレット、ノート PC。私たちのウェブを見るために使っている端末には 2 個、 4 個、あるいはそれ以上のプロセッサが積み込まれています。また高性能な GPU を 1 つ以上搭載していることも珍しくなく、その力でレンダリングやその他の処理が高速化されています。

またウェブはハイパーリンクによって繋がった静的な文書の集まりから、インタラクティブで動的なアプリの集合へと、この 15 年で変化しました。遅延のなさや、リッチなアニメーション、リアルタイムなインタラクションを開発者だけでなく、一般の利用者も求めています。このような体験を可能なものとするためには、のは、並列処理やハードウェアに固有な複雑性に煩わされることなく、デバイスの能力を最大限まで利用できるウェブプラットフォームが必要です。

つまり Quantum とは、現代のデバイスが持つ処理能力を最大限まで利用し、未来のウェブのニーズを満たす次世代型のウェブエンジンをつくるプロジェクトです。 Gecko を出発点とし、そのコンポーネントを並列処理を利用したものや GPU へのオフロードを利用するものへ置き換えてゆきます。これを行う上で重要な要素の 1 つは、Servo の革新的なコンポーネントの取り込みです。Mozilla がスポンサーしている独立コミュニティによって開発されている、このウェブエンジンと、コンポーネントを一部共有するところから始めますが、それぞれのプロジェクトの進展に応じて、より多くの要素の組み込みも試みます。

Quantum のコンポーネントの多くは Rust で実装されています。 Rust は処理がとても速いプログラミング言語で、スレッドとメモリの安全を保証することで並列プログラムの開発を単純化します。ほとんどどの場合、安全でない Rust のコードはコンパイルできません。

Quantumの一環として、お互いに関係する取り組みをいくつも行っており、あわせて過去には当然とされてきた前提や、実装も再検討しています。つまり、ブラウザエンジンの仕組みを根本から考え直すのです。 CSS スタイルの反映や DOM 操作の実行、画面のレンダリングなど、ウェブエンジンの基礎となる部分も再開発します。

Quantum は野心的なプロジェクトですが、その成果を実感するまでに長い時間待つ必要はありません。来年には大きな改良を提供を始め、順次リリースを行います。まずは Android 、 Windows 、 Mac 、 Linux 向けの提供ですが、いつの日か iOS にも提供できることを願っています。

Quantum はブラウザのパフォーマンスマンスを飛躍的に向上させると確信しています。このプロジェクトに関わろうとお考えの開発者の方は、 Mozilla Wiki の Quantum に関するページをぜひご覧ください。一緒に飛躍的な成長を遂げましょう。

Firefox 51 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 51 の翻訳です]

Firefox 51 が 1 月 24 日 [日本時間同日深夜] リリース となります。なお、12 月 13 日にはメジャーリリースではなくマイナーリリースが予定されているため、今回は普段より相当長いリリースサイクルとなります。Firefox 51 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 51 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

XPCOM とモジュール

新機能

  • 組み込み WebExtension: 再起動不要型アドオンに WebExtension を組み込めるようになったおかげで、この新しいプラットフォームへ徐々にコードを移行したり、保存したデータを WebExtension で扱える形式に変換したりすることが可能となりました。
  • WebExtension Experiments: これは、Mozilla (やアドオン作者の皆さん) が新しい WebExtension API を試作できるようにするための仕組みです。

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 51 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 50 対応のアドオンを登録している方は後日メールをチェックしてみてください。

debugger.html の開発に際して

この記事は Mozilla Tech に投稿された “Introducing debugger.html” の抄訳です。

プロジェクトに関わっていると、現在と未来とを股にかけている感じがすることがあります。目の前にはとても大きな可能性が横たわり、それが日々高まっていく感覚。Firefox の開発ツールチームの最新プロジェクトである debugger.html に関わっていると、それを実感します。debugger.html とは Firefox とウェブのために設計された、新しい JavaScript デバッガーで、いずれ Firefox に統合され、現在のデバッガを置き換える予定です。これを作る過程で、デバッガー自身の実装、メンテナンス、そして使い方を考え直しています。

debugger.html のスクリーンショット

devtools-html/debugger.html で開発されている debugger.html

このデバッガーはもうすぐ Nightly 版の Firefox で利用できるようになります(Nightly 版 Firefox のダウンロードはこちら)。

このプロジェクトが始まってすぐのころ、プロジェクトの継続を諦め 1 からの作り直しを決定する理由について考えることに注力しました。このことについて デバッガーのリードである James Long が React Rally で素晴らしい講演をしています。これまで開発してきたデバッガーをリファクタリングすることもできました。そしてFirefox の他のチームが実際にリファクタリングをしていました。これには様々な利点があります。そのチームはウェブコンソールを同じようなアーキテクチャへとリファクタリングしています。しかし私たちのチームは、コードを 1 から書き直すという異なるアプローチを選択しました。Firefox の中のコードをリファクタリングすることを選択したコンソールと、Firefox の外の世界で生きることを選んだデバッガー。両方のチームは、それぞれのやり方の利点と困難さについて知見をためています。

debugger.html は React と Redux というモダンなウェブアプリのアーキテクチャを利用して、スクラッチからデバッガを作成しています。2016 年にプロジェクトは始まりました。その時点でレポジトリは空っぽでしたが、チームはデバッガーやツールの開発経験が豊富なメンバーで満たされていました。これまでのデバッガーは XUL と呼ばれる(ディナはいません。ズールだけです)、オープンではありますが、事実上プロプライエタリで、Firefox だけがサポートするマークアップ言語で作成されています。変更の困難さのほとんどは、この XUL に起因していました。なぜなら、XUL にはモデルとビューコンポーネントが入り組んでいて、簡単にできるはずの単純な変更も許さないようになっていたからです。Firefox の開発ツールは全て XUL から離れ、再利用性の高い React コンポーネントと Redux のストアモデルを採用したアーキテクチャへと移ろうとしています。コードをより小さなモジュールへと単純化が可能なこの変更によって、開発ツールの振る舞いの予測や、コードの理解、テストが容易になり、開発がより簡単になることでしょう。

また debugger.html は Firefox での利用だけを想定したものではありません。もちろん Firefox に向けた開発を優先してはいますが、複数のプラットフォームをターゲットとできるようにモデルを一般化し続けてもいます。製品としてリリースするには至っていませんが、Chrome Debugging Protocol 経由で Chrome のタブや Node のプロセスにアタッチすることも可能です。また再利用性の高いコンポーネントを利用して実装していることにより、エディタへの組み込んだデモや CLI のデモも行なっています。必要とされる UI コンポーネントは一部だけだとしても、アプリケーションモデルは意図したとおりに働き、多くの再利用の可能性を実現するでしょう。

ウェブ開発者ならこの新しいデバッガーを違和感なく使え、その新しい点にもすぐに気づくことでしょう。

debugger.html のソースパネル

ソースパネルはデバッガーの左側に配置されています。ここにはソースコードがフォルダごとにまとめられており、従来よりもより簡単にデバッグするソースコードを探し出せます。

右側にコールスタックや、スコープ、ブレークポイントといったデバッグに必要な情報が、使いやすくまとめられています。

すべての Mozilla のコードと同様、debugger.html のコードはオープンソースで、手がつけやすくなっています。debugger.html プロジェクトは Github 上にあり、必要に応じて更新できるよう、Firefox と密接に関連しています。プロジェクトのサイズは小さく、焦点を絞ったもので、コードのすぐそばに説明が書かれています。すでに数々の貢献者がいて、プロジェクトが見つけやすく、管理しやすく、取り組みやすいものであることを証明しています。

これは第一歩にすぎません。Firefox の開発ツールが持つ全ての機能が、ここにまとめられる予定です。今後の数ヶ月は、開発に参加したい人が、開発を始めやすいよいうにする作業に注力する予定です。また他のプラットフォームをどのように統合するかについて調査もする予定です。そして、Firefox とその他のプラットフォームに向けてのリリース方法について研究をする予定です。

debugger.html は開発者によって、開発者のために開発されているデバッガで、デバッグ方法の改善に興味のある全ての人に向けてデザインされています。このようにオープンなやり方で開発されているツールは、他にはありません。あなたの貢献がツールをよりよくします。ぜひ GitHub で、開発に参加してください。

Hacks ブログにも debugger.html についての情報が掲載されています。技術的な詳細はそちらを参照してください。

Nightly 版が実験的に HTC Vive をサポートしました

この記事は “Experimental HTC Vive Support in Firefox Nightly” の抄訳です。

HTC Vive の写真

去る 9 月 1 日、Firefox の Nightly 版が HTC Vive のヘッドセットを実験的にサポートし、OpenVR API から操作できるようになりました。これは計画されているハードウェアサポート拡充の一環で、その他に関しては数週間のうちにアナウンスされる予定です。そのアナウンスには HTC Vive のコントローラーや Oculus Touch コントローラー、OSVR ヘッドセットへの対応も含まれます。また Firefox は OSVR API を利用して、Mac と Linux での WebVR にも対応する予定です。

HTC Vive は Lighthouse と呼ばれるトラッキングシステムを持っています。これは部屋の中で、VR ヘッドセットの位置と向きをトラッキングするためのシステムです。これに対応することで、WebVR サイトの中を自然に歩きまわれるようになりました。

HTC Vive を利用している様子はこちらをご覧ください:https://vine.co/v/ilPIP65QqFE

この HTC Vive へのサポートは実験的なもので、コントローラーへの対応は別途行われる予定です。とはいえ、次の手順で設定を行うことで、HTC Vive のヘッドセットを WebVR で利用できるようになります。

  1. Firefox をリフレッシュして、まっさらなプロファイルを作成します。これは WebVR 向けの設定が、Nightly 版の動作に問題を引き起こす可能性があるからです。
  2. GitHub から openvr_api.dll のバージョン 1.02 をダウンロードします。64 ビット版の Firefox 向けの dll はこちらから、32 ビット版はこちらからダウンロードしてください。64 ビット版の Firefox の利用をお勧めします。
  3. openvr_api.dll を Firefox の読み取れる場所に保存します。例えば “C:\openvr” のようにフォルダを作成し、そこに保存すると良いでしょう。
  4. Nightly 版 Firefox の “about:config” を開きます。
  5. “dom.vr.openvr.enabled” の値を “true” に変更します。
  6. “gfx.vr.openvr-runtime” に、先ほど保存した openvr_api.dll の場所を、”C:\openvr\openvr_api.dll” のようにフルパスで設定します。
  7. Nightly 版 Firefox を再起動します。

動作テストは、WebVR 1.0 examplesSketchFab で行えます。これらは部屋のサイズの WebVR に対応しています。自分自身でコンテンツを作成される場合は、A-Framethree.js、詳細は WebVR 1.0 の仕様を参照してください。

debugger.html のご紹介

[この記事は "Introducing debugger.html" の抄訳です]

debugger.html は Mozilla の作成したモダンな JavaScript デバッガで、React と Redux を使って実装されています。これは Firefox の開発ツールに組み込まれているデバッガを置き換えるためのプロジェクトで、今年の初めに始まりました。また複数のターゲットに対してデバッグできることや、単体での動作も目的としています。

debugger.html のスクリーンショット

現在は Firefox、そして実験的な機能として Chrome、そして Node に接続し、デバッグを行えます。Firefox への接続には Mozilla のリモートデバッグプロトコル (RDP) を、Chrome と Node への接続には Chrome の RDP を利用しています。

このプロジェクトは GitHub で公開されています。またモダンなフレームワークと、ツールチェーンを利用しています。多くの開発者にとって魅力的で、簡単に見つけられるようになっています。

debugger.html

debugger.html のユーザーインタフェースは、ソースパネル、エディタパネル、サイドバーの 3 つに分かれています。

  • ソースパネルには、ソースコードがツリー状に表示されます
  • エディタパネルには様々なソースファイルの表示が可能です。またソースコードを整形して見やすく表示する機能やブレークポイントの設定機能も持っています
  • サイドバーには、現在設定されているブレークポイントが表示されます。プログラムがブレークした時には、その時点でのコールスタックと、変数が表示されます
    • 一時停止、ステップオーバー、ステップイン、ステップアウト、復帰といった、デバッグのための機能を提供します
    • 実行が一時停止されると、その時点でのコールスタックがコールスタックパネルに、スコープパネルには変数がツリー状に、それぞれ表示されます

デバッグ中の画面

はじめかた

debugger.html を使うには、まず GitHub からコードをチェックアウトし、 Getting Started を読むところから始めましょう。

すぐ使い始めたいなら、次のコマンドを実行してください:

npm install - Install dependencies
npm start - Start development web server
open http://localhost:8000 - Open in any modern browser

8000 番ポートへアクセスすると、デバッガーが表示されます。デバッグ対象が選択されると、そのターゲットに対し接続し、リモートデバッグを開始します。これには、ターゲットにいくつかの項目を設定しなければなりません。例えば MacOS 上で動作する Firefox に接続する場合には、次のコマンドを実行してリモートデバッグを許可する必要があります。

$ /Applications/Firefox.app/Contents/MacOS/firefox-bin --start-debugger-server 6080 -P development

Chrome や Firefox で利用するその他オプションはこちらを参照してください。

Node 上で動くコードをデバッグするには、v6.3.0 以上の node.js が必要です。inspect オプションをつけて Node を起動すると、デバッグができます。例えば myserver.js をデバッグするには、次のように実行します。

$ node --inspect myserver.js

詳細は Getting Started を参照してください。

Firefox の開発ツールとの関係

Firefox に組み込まれている開発ツールとの統合を進めています。最初の統合が終わり、Nightly 版で利用できるようになっています。

Nigntly 版に統合された debugger.html

開発に参加するには

このプロジェクトは開発の途中です。皆様の参加は心から歓迎します。一緒に最高のデバッガーをつくりましょう。開発へ興味をお持ちの方は、まず貢献のための手引きをごらんください。

Bryan Clark について

Firefox 開発ツールのプロダクトマネージャ。

Twitter:@clarkbw

Bryan Clark によるその他のドキュメントはこちら

Firefox 50 アドオン互換性情報

[これは Mozilla Add-ons Blog の記事 Add-on Compatibility for Firefox 50 の翻訳です]

Firefox 50 が 11 月 8 日 [日本時間同日深夜] リリース となります。Firefox 50 の変更点でアドオンの互換性に影響を及ぼす可能性のあるものを以下にまとめました。Firefox 50 for Developers により詳しい情報が載っていますので、こちらも併せてご覧ください。

一般

XPCOM とモジュール

新機能

この一覧に載っていない変更点や間違いを見つけたらコメント欄でお知らせください。もしあなたのアドオンが Firefox 50 で動かなくなった場合は、筆者の方でも調査したいと思います。

AMO に登録されているアドオンの 自動互換性テストと対応バージョンの更新 は数週間以内に行われますので、AMO に Firefox 49 対応のアドオンを登録している方は後日メールをチェックしてみてください。

What’s new in Web Audio?

この記事は “What’s new in Web Audio?” の抄訳です。

Web Audio API は以前開発中です。つまり新しいメソッドや属性の追加、名称の変更、入れ替え、そして削除もありうるということです。

この記事では 2015 年初頭の時点からの Web Audio と、その Firefox における実装との変更点についてまとめます。参照しているデモは Firefox の Nightly 版で動作します。リリース版や Developer Edition では対応していない変更点もありますから、ぜひ Nightly 版で試してください。

API の変更

破壊的なもの

DynamicsCompressorNodereduction 属性は AudioParam ではなく float となりました。その結果、compressor.reduction.value ではなく compressor.reduction を参照することで、値を読み出せるようになりました。

この値は入力シグナルに対して適用される減衰量を表します。以前よりリードオンリーの値であり、スケジュールされた値の変更が必要ないため、AudioPArame ではなく float への変更は妥当なものでしょう。

ブラウザのサポートするのが AudioParam なのか、それとも float なのかは、reduction の value 属性を参照することで判断できます。

if(compressor.reduction.value !== undefined) {
  // old style
} else {
  // new style
}

こちらでは、ドラムループが再生され、それに応じて reduction 属性の値が変化する様子がみられます。この値はトラックの音の大きさに合わせて変化しています。またブラウザがサポートする API のバージョンの判定方法も、併せて確認できます。

新しい属性とメソッド

AudioContext へ追加されたライフサイクル管理用メソッド

AudioContext の生成のコストは高かいため、suspend()resume()close() の 3 メソッドが追加されました。

これらのメソッドを利用することで、音声処理を必要になるまでサスペンドしたり、AudioContext が必要なくなった場合に close() を呼んでリソースを解放するといったことが可能になりました。

AudioContext がサスペンドされた場合、音声は再生されません。レジューム時にはサスペンドされた位置から再生されます。詳細については、suspend() の解説を参照してください。

これらのメソッドの利用例は、こちらのデモで見られます。

正確になった AudioNode の disconnect()

disconnect() を呼ぶと、接続されている全てのノードから切り離されてしまったため、特定のノードだけを選択的に切断することはできませんでした。

望まれる切断方法が多様化したため、使い方にあわせて disconnect() メソッドをオーバロードできるようになりました。

  • disconnect():全てのノードへの接続を切る(既存の機能)
  • disconnect(outputNumber):指定された出力チャンネルから、ノードへの接続を全て切る
  • disconnect(anotherNode):指定されたノードへの接続を全て切る
  • disconnect(anotherNode, outputNumber):このノードの outputNumber で指定されたチャンネルから anotherNode への接続を全て切る
  • disconnect(anotherNode, outputNumber, inputNumber):このノードの outputNumber で指定されたチャンネルから、anotherNodeinputNumber で指定されるチャンネルへの接続を全て切る
  • disconnect(audioParam):このノードから指定された audioParam への接続を全て切る
  • disconnect(audioParam, outputNumber):このノードの outputNumber で指定されたチャンネルから、audioParam への接続を全て切る

これらの切断に関する処理について理解するには、AudioNode の仕様を読むことを強くお勧めします。また変更が行われた理由については、こちらの議論を参照してください。

OfflineAudioContext への length 属性の追加

この新しい属性の値は、OfflineAudioContext の初期化時に実行されるコンストラクタの引数によって決まります。そのため、その値を別の変数に保存する必要がなくなりました。

var oac = new OfflineAudioContext(1, 1000, 44100);
console.log(oac.length);
>> 1000

こちらのデモではこの属性の使用例と、ゲインエンベロープを利用した音声の生成例が見られます。

AudioBufferSourceNode への detune 属性の追加

これは OscillatorNodedetune 属性と同様のものです。既存の playbackRate 属性よりも正確にサンプリングした音声を調整できます。

PannerNode に AudioParam 型の属性 position と orientation の追加

AudioParam 型の属性が追加されました。これらを利用することで、setPoistion()setOrientation() を呼び続けなくても、それらの変化を自動化することができます。

StereoPannerNodepan 属性はすでに AudioParam になっています。そのため音声のパンニングを扱うノードのは全て、自動的にその位置に関する属性を変更できるようになりました。これはモジュラーシンセを作るのに、とても便利なものたちです。

しかし AudioListener の位置と向きに関する属性を自動的に変化させることは、まだできません。つまりこれらの値を時間に応じて変化させるには setPosition()setOrientation() を定期的に呼び出す必要があるのです。この問題は Bug #1283029 にファイルされています。

PeriodicWave の初期値指定

PeriodicWave オブジェクトを作成する際に、オプションをオブジェクトで渡せるようになりました。

var wave = audioContext.createPeriodicWave(real, imag, { disableNormalization: false });

比較のため、以前の書き方を載せておきます:

var wave = audioContext.createPeriodicWave(real, imag);
wave.disableNormalization = false;

将来的には、ノードを作成する全てのメソッドで初期値を渡せるようになります。またコンストラクタも利用できるようになるため、GainNode の作成もこのように行えます:new GainNode(anAudioContext, {gain: 0.5});。 これで初期化が必要な Web Audio のコードをより簡潔に書けるようになります。メンテナンスするコード量が減ることは、常にいいことですよね!

新しいノードの追加:IIRFilterNode

IIRFilterNode を利用した例のスクリーンショット

BiquadFilterNode では力不足と感じた場合、IIRFilterNode を使ってカスタムフィルタを作成すると良いでしょう。

AudioContextcreateIIFilter() メソッドに、フィードフォワードとフィードバックの二つの係数を配列で与えることで、フィルタを作成できます。

var customFilter = audioContext.createIIRFilter([ 0.1, 0.2, ...], [0.4, 0.3, ...]);

このフィルタノードのパラメータを自動的に変化させることはできません。つまり一度作成したら、その値は変更できません。そのような変化をさせたいのであれば、BiquadFilter を利用し、AudioParam で指定できる Q / detune / frequency / gain の各属性を適切に設定することになります。

これらの違いについては仕様を読むと、より理解できるでしょう。また Digital Filter Design も便利なツールです。ここではフィルタのデザインとフィルタの可視化が可能で、feedforwardfeedback を含む使用可能なコードが生成されます。

メソッドチェーン

書きやすさのために、いくつかのシンタックスシュガーも追加されました。

connect() メソッドは接続先のノードを返すようになったため、複数のノードの接続を簡単に書けるようになりました。

以前:

node0.connect(node1);
node1.connect(node2);
node2.connect(node3);

今:

node0.connect(node1).connect(node2).connect(node3);

また AudioParam の自動化メソッドも呼び出し先のノードを返すようになったため、メソッドチェーンを行えるようになりました。

以前:

gain.setValueAtTime(0, ac.currentTime);
gain.linearRampToValueAtTime(1, ac.currentTime + attackTime);

今:

gain.setValueAtTime(0, ac.currentTime)
  .linearRampToValueAtTime(1, ac.currentTime + attackTime);

これから

Web Audio ワーキンググループは AudioWorklet に関する仕様の記述をほぼ終えています。これは AudioWorker の新しい名前です。これは ScriptProcessorNode を置き換えることになっています。これは ScriptProcessorNode が開発者が定義した任意の音声処理を UI スレッドで行うため、パフォーマンスの面で改善の余地があったためです。

AudioWorklet と関連するオブジェクトを定義し、仕様に追加するプルリクエストのマージが最初に行われるでしょう。その後、各ブラウザベンダが AudioWorklet の実装に入ります。

Firefox:パフォーマンスとデバッグにおける改善

3 人のエンジニア(Karl Tomlinson, Daniel Minor and Paul Adenot)の 6 ヶ月以上の奮闘により、Firefox の Web Audio に関するパフォーマンスは改善されました。実践的な面から見ると、音声に関するコードは Chrome よりも同等以上のスピードで動作するようになりました。唯一の例外が AudioParam に関連するもので、そのパフォーマンスはまだ良いとは言えません。

同様にメインスレッドが重たい時によく起きていた ScriptProcessorNode の遅延も少なくなくなりました。これはコンソールエミュレータのようなアプリケーションには大きな改善です。低遅延はエミュレーションの信頼性を高め、その結果として多くのゲームを楽しめるようになるからです。

より深い話としては、DSP カーネルの計算にアセンブラレベルでの最適化が行われました。ARM と x86 の SIMD 命令の長所を利用して、パンニングやゲインの調整といった簡単な計算で、複数の値を並行に計算するようになりました。これによってコードの実行が高速かつ効率的になり、モバイル環境では特に重要なバッテリー消費もより少なくなりました。

また MediaElement ノードで発生する cross-origin エラーが開発ツールのコンソールへ表示されるようにもなりました。以前はこのエラーが報告されないまま失敗するため、コードが止まる理由を考えるのが大変でした。この変更によって、その原因コードの特定が簡単になりました。

これら以外にも多くのバグが修正されました。ここに書くには多すぎるくらいですが、こちらのリストでそれらを確認できます。

Soledad Penadés について

Sole は Mozilla の Developer Relation チームの一員で、Web で素晴らしいものが作られるのを助けています。なかでもリアルタイムに関するものが好みです。irc.mozilla.org の #devrel でコンタクトできます。

Soledad Penadés によるその他の記事はこちら。

Developer Edition 50:コンソール、メモリツール、ネットワークモニタ、etc

この記事は “Developer Edition 50: Console, Memory Tool, Net Monitor and more” の抄訳です。

Firefox Developer Edition のバージョン 50 が公開されました。今回の更新では、スクリプト由来のリクエストのモニタや、IndexedDB に保存されているデータの操作など、多くの点で改良がなされています。これ以外にずっと欲しかった機能も紹介します。

コンソール

待ちわびた機能がついにやってきます。その機能とはソースマップです。この機能は最終のテスト段階で標準では off になっていますが、ぜひ試してフィードバックを送ってください。

ソースマップが実現の困難な機能であった理由については、James Long による解説記事があります。そちらをご覧ください:On the Road to Better Sourcemaps in the Firefox Developer Tools

そんな困難な機能の実装がどうして始まったか、興味はありませんか?Joe Walker によると、その理由は次のようになるそうです:

インターンは背景知識を十分に持っていない場合があって、バグの難しさを見誤ることも多い。その結果、本当に難しいバグにチャレンジすることになってしまうことも、ときおりある。ま、それがインターンなんだけどね。

解決をした Firefox の開発ツール担当インターン Jaideep Bhoosreddy に大きな感謝をしたいです。

ソースマップを利用することで、ダウンロード時間の短縮のために JavaScript ファイルを圧縮したり、TypeScript や CoffeeScript といった他のフォーマットから変換して JavaScript を作成することが可能になり、しかも元のファイルとの関係性も維持されるためデバッグが簡単になります。

デバッガはすでにソースマップに対応していますが、コンソールは今まで対応していませんでした。その結果、出力されたログに含まれるファイルや行番号といった位置は、変換後の JavaScript ファイルのものとなってしまって、ほとんど利用価値がなくなってしまいます。

しかしそれも過去のことです。、コンパイル後のものではなく、オリジナルのソースファイルの位置がコンソールに表示されるようになります。次の例は CoffeeScript ファイルの位置を表示しています:

コンソール中に表示されている行番号をクリックして、対応する CoffeeScript が適切にデバッガで表示する様子

ソースマップに対応したコンソール

コンソールのソースマップ対応機能は標準ではオフになっており、有効にするには設定を変更する必要があります。これはソースマップの作成に利用したツールにごとにいくつかの実装があるため、それらの幾つかをテストしたいと思っているからです。これが現在の状況です。

コンソールをソースマップに対応させるには

ソースマップに対応したコンソールを利用するためには、以下の手順に従って設定を変更します。

  • URL バーに about:config と入力する
  • devtools.sourcemap.locations.enabled を検索する
  • その項目をダブルクリックし、値を true に変更する
  • about:config を閉じ、コンソールを再び開く

about:config の項目を変更し、コンソールのソースマップ対応を有効にしている

何かおかしい点を発見したら、Twitter で @firefoxdevtools に宛ててつぶやくか、IRC の #devtools チャンネルでご相談ください。

ネットワークスタックトレース

Firefox Developer Edition バージョン 50 では、HTTP ログからリクエストを送信した際のスタックトレースが見られるようになりました。この機能は標準で利用できます。

HTTP リクエスト送信時のスタックトレースが、コンソールに表示されている

メモリツール

メモリツールも標準で利用できるようになりました。デバッグとパフォーマンチューニングには欠かせないツールです。これを利用することで、メモリリークの発見と修正が簡単になります。このツールの詳細については、MDN の記事、もしくは Hacks の “Firefox’s New Memory Tool” という記事をご覧ください。

ネットワークモニタ

Firefox バージョン 49 で、”Cause” 列が追加されました。ここにはネットワークリクエストの発生理由の種別が表示され、可能であればスタックトレースも表示されます。スタックトレースはポップアップで表示されるのですが、今回の更新でここに、XHR や Promise、setTimeout といった非同期通信時のフレームが表示されるようになりました。ちょうどデバッガにおけるスタックトレースパネルと似たものとなっています。

非同期通信のフレーム情報が追加されたネットワークモニタ

また列のヘッダをクリックすることで、通信ログを原因ごとに並び替えられます。これは fetch によって発生したリクエストを早く探したい、といった場合に便利な機能です。

JSON ビューワ

JSON ビューワも改善され、よりスマートにデータを表示するようになりました:

ストレージインスペクタ

Mike RatcliffeJarda Snajdr の泥浴によって、ストレージインスペクタも改良されました。その結果、コンテキストメニューから IndexDB 中の項目を 1 件ずつ削除できるようになりました。

コンテキストメニューから、IndexDB 中の項目を削除する様子

about:debugging

Web 開発における次のビッグウェーブといえば、Service Worker でしょう。オフライン時の機能や、プッシュ通知といったネイティブアプリの持つ機能を備えた Web アプリである Progressive Web Apps を作るには、Service Worker の提供するツールを利用します。Firefox では、about:debugging#workers というページで登録された Service Worker の管理できます。今回の行為新で、このページで各 Service Worker が利用するプッシュ通知のエンドポイントも表示されるようになりました。またテスト用の通知を送るためのボタンも併せて追加されています。

about:debugging#workers の画面

その他の変更点

アイコン:開発ツール内のアイコンが一貫性とシャープさが出るように変更されました

Firefox 49 でのアイコン

Firefox 49 でのアイコン

Firefox 50 で変更されたアイコン

Firefox 50 でのアイコン

WebAssembly:Luke Wagner が以前のブログポストで述べています:

WebAsssembly は策定が進んでいる標準の一つで、その目的は安全性とポータビリティを維持しつつ、サイズとロード時間の面で効率的なバイナリフォーマットの定義です。

デバッガはすでに WebAssembly ファイルにも対応しています。またシンタックスハイライトもできるようになりました。

シンタックスハイライトされている WebAssembly ファイル

シンタックスハイライトされている WebAssembly ファイル

最後に小さいけれど便利な変更点を一つ:スタイルエディタを無効にできる機能が追加されました。これでスタイルエディタのアイコンが占めていたタブ上のスペースを節約できます。

以上で Developer Edition バージョン 50 の機能紹介は終了です。最新版をダウンロードして、フィードバックを送ってください。最後に今回追加された多くの改善に貢献されたすべての人に大きな感謝を示したいと思います。ありがとうございました。

開発ツールはスタンダードな HTML、JavaScript、CSS で開発されています。フロントエンジニアとしての経験があれば、その開発に参加できます。開発ツールの開発に興味をお持ちの方は、まず http://firefox-dev.tools/ にある簡単なバグから始めてみてはいかがでしょうか。参加はいつでも歓迎します。

Nicolas Chevobbe について

Nicolas Chevobbe による他の記事はこちら

js13kGames:コードゴルフ型ゲーム開発大会

この記事は “js13kGames: Code golf for game devs” の抄訳です。

13KB。KB なんて最近では雀の涙ほどのデータ量ですが、ゲームの歴史を遡れば先駆者たちはとんでもない制約の中でゲームを作ってきたということに気づくはずです。

一例を挙げると、皆に愛されたアタリ 2600 の RAM は、ほんの 128 バイトしかなく、カセットをさしても 4 KB 増えるだけでした。ことわざにもある通り、制約は創造の母です。そんなゲームのコンペティション、js13kGames の季節がやってきました。これは zip 圧縮して 13,312 バイト以内であることを条件に、ゲームの創造性を競う大会です。

HTML5 ゲーム開発者向けの大会

js13kGames は HTML5 でゲームを作る開発者のための大会で、2012 年より毎年開催されています。作成するゲームのファイルサイズが 13KB に制約されている点が特徴的な大会です。8 月 13 日から 9 月 13 日の 1 月間で、与えられたテーマのもとにゲームを作成します。2015 年のテーマは「逆転」(Reversed)でした。

js13kGames のロゴ

旧友とスポンサーの助力により、多くの景品が用意されました。達人であることを示す盾や、無料の T シャツ、その他のグッズが世界中に無料で送られました。そうはいっても、参加者の唯一の目標は勝利そのものです。js13kGames コミュニティに参加することで得られるものはたくさんあります。詰まった時の助けや、ツールやワークフロー、TIPS、技巧といった知見が共有されるでしょう。そして限られた期間でゲームを完成させる体験は、あなたの腕を大いにあげることになるでしょう。

昨年の優勝作品

13KB は低解像度の作品であっても十分とは言えないファイルサイズです。登録されたゲームを紹介したページの小さいスクリーンショットでさえ、そこに登録されているゲーム自体より大きいなんてことはよくあります。それでも、その素晴らしさに驚くことになるでしょう。去年の優勝作品の中からいくつかを紹介します:

こんなものをどうやって実装したか不思議に思いませんか?私は優勝者にインタビューをして、その秘訣をいくつかを共有してくれるようお願いしました。そしての結果、極限まで制約された環境下でゲームを作るために、彼らが使ったツールやテクニックを共有してもらいました。全てのゲームは GitHub で公開されています。それらを見れば、彼らが何をしたかを詳細まで知ることができます。

RoboFlip

RoboFlip のプレー画面

Eoin McGrath が RoboFlip を作った際のワークフローについて、次のように述べています。

最終的には zip でゲームを提出します。複数のファイルを圧縮するより、単一のファイルの方が効率良く zip 圧縮できます。だから全画像をインラインで記述し、JavaScript をミニファイして、全部のスペースを除去するのが最も最善でした。Grunt や Gulp のようなタスクランナーのおかげで、このプロセスのほとんどの部分を自動化できました。詳細は Gulpfile を見てください。単に gulp buildと叩くだけで、面倒なことが全てすみ、どれだけのサイズが残されているかがわかるようになっています。

gulp build を実行して、ファイルが圧縮され、使用可能な容量が表示されている。

グラフィックス

最初に高解像度のスプライトを、アニメーションフレーム付きで利用することは諦めました。単純化が鍵です。多くのものはプロシージャルに生成されるか、SVG を利用しました。レトロなピクセル感が好きなので、まず Gimp で全ての画像を 6×6 ピクセル程度の低解像度で作成しました。それらを base64 でエンコードし、canvas に再描画することで拡大しています。

利用されているスプライト

他のすぐに使えるテクニックには、不透明な色を白に変える関数です。

通常状態の絵を、関数で白くすることでダメージを受けた状態を表現している

これで全てのスプライトに対してダメージを受けた状態のフレームを効率的に用意できます。

サウンド

音のないゲームはカフェインのないコーヒーみたいなものです。ファイルサイズの制限から、.mp3.ogg ファイルなんてただの1つも使えません。jsfxr という便利なライブラリを利用することで、ゲーム中で利用する 8ビットのようなビープ音を生成しています。

音楽という点では Sonant-X library を使ってサウンドトラックの基本を作ってもいいでしょう。どんなものかはこのすごいデモを見ればわかるでしょう(まず “Play Song” を押して初期化する必要があります)

Road Blocks

js13kGames が好きな理由の 1 つが、人工的に課せられた制約です。これは言い換えれば達成可能なものだからです。そうオーストラリア出身のゲーム開発者 Ash Kyd は書きました。

インディーの開発者として、終わりのないプロジェクトをやることで、どんどんはまってしまい、最後には見せるものが何もないという状態になってしまう可能背があることに気づきました。でも厳しい制約は何を成し遂げられるかという点で創造的にしてくれます。

Road Blocks のプレイ画面

ファイルサイズへの制限のおかげで、Road Blocks は本質的にシンプルなゲームになり、多量のコーディング作業を必要としませんでした。その結果として、期間中の多くを試遊とゲームの改良に費やせました。その結果、ひと月後にはとても質の高いゲームが完成しました。

Behind Asteroids – The Dark Side

js13kGames は WebGL や Web Audio のような優れたテクノロジーを見つけて実験し、スキルを磨くのにとてもよい機会です。13 kB の制限のおかげで、フレームワークの陰に隠れることもできません。また画像も使えないため、それらのプロシージャルな生成にトライしなくてはいけません。だから自分次第で、自分にあったやり方や技巧を見つけられるのです。すぐに技巧に走ってはいけません。まずプロトタイプを作ってから、最後にコードを圧縮するのです。

そうゲーム開発のベテランであり、js13Games の優勝者でもある Gaëtan Renaudeau はアドバイスしていました。

Behind Asteroids - The Dark Side のプレー画面

面白いテクニックの一つに、ファイルサイズを小さくするためにオブジェクト指向的な書き方を避けることがあります。その代わりに関数と、タプル型としての配列を利用しました。私はこのテクニックを、前身の js1k に参加するより前に使ったことがありました。

js13kGames に参加して 3 年になります。そして毎回 WebGL を楽しんできます。2015 年の作品は Asteroids のリメイクです。このゲームでは宇宙船をコントロールすることはできません。そのかわり小惑星を送ることがでいきます。これが私なりの「逆転」の解釈です。

デスクトップでは、このベームはタイピングゲームとなります。それぞれの小惑星に割り振られている文字を、適切なタイミングでタイプすることでゲームを進めます。モバイルではシンプルなタッチゲームとしてプレイできます。

このゲームは、初心者から熟練のプレーヤーまで、さまざまなレベルの人が楽しめます。プレーヤーは AI アルゴリズムによってコントロールされる宇宙船の乗組員ですが、実際には小惑星をコントロールしてその宇宙船を破壊しなければなりません。

ゲームの描画方法

このゲームの描画はハイブリッドで行われています。まず canvas 上に基本的な 2 次元グラフィックスを描画します。それを WebGL で複数の後処理を加えることで描画を行っています。

2 次元グラフィックスではパーティクルとなる円や、宇宙船や隕石となる多角形、プロシージャルなフォントとして利用する線を描画します。なおこのフォントで使える文字はハードコードされています。これらは赤、青、緑のいずれかの色をつかって描かれます。これは、例えば青で塗られた円に対してのみ特別なグレアイフェクトをかけるといったような、グループに分けての後処理を可能にするためです。これはモノクロなゲームで使える、異なるものを 1 つのテクスチャにまとめて最適化するための面白いテクニックです。

さまざまなイフェクトが WebGL を用いた後処理として実現されています。詳しくはこちらの記事に述べましたが、この最終ステップの最大の目的はオリジナルのアーケードゲームで使われていたベクターグラフィックスの再現です。

アーケードゲームのスクリーンを模して表示されるマップも、背景に追加されます。これは全てがフラグメントシェーダによって生成されています。

まとめ

コードを小さくするためのテクニックは比較的よく知られたものから、無名のものまで無数にあります。Turs+ Game Development に HTML5 ゲームをミニファイする方法のまとめが掲載されていますし、js13kGames Resources にもツールやマテリアルのまとめがあります。

この記事で js13kGames の概要と過去の優勝作品が使っていたコードゴルフテクニックがつかめましたか?今年のトーナメントに参加されたいですか?数日後の 8 月 13 日に始まります(訳注:元の記事は 2016 年 8 月 8 日に公開されました)。ぜひこちらから参加してください。コード書くのに遅すぎた、なんてことはありません。

Andrezej Mazur について

HTML5 ゲーム開発者で、Enclave Games のファウンダー。Gamedev.js という週間メルマガの発行人で、HTML5 ゲーム開発者向けのコーディング大会である js13kGames の発起人。新しいオープン Web 技術について技術講演を行い、WebVR に夢中になっている。

Andreij Mazur による他の記事はこちら