2011-12-30

最近のゲームのグラフィックに思う

グラフィックは、ゲームの面白さの本質ではない。しかし、やはりグラフィックは重要である。私が始めた遊んだPCゲームは、Mafiaであった。Mafiaは、当時としては素晴らしいグラフィックであり、私のGeForce 4 Ti4200で快適に動作した。

今から思うと、惜しいことをしたものだ。私はもっと早くからPCゲームに目覚めているべきだったのだ。DoomやWolfenstein 3DやDuke Nukem 3Dなどといった往年の名作ゲームが、今となっては楽しめない。もし当時、これらのゲームに触れていれば、楽しめたはずなのだ。しかし、私の最初のPCゲームはMafiaだったので、それより以前の時代のゲームを楽しめないのだ。これは実に残念なことだと思う。私はThe Elder Scrollsシリーズが好きだが、ArenaやDaggerfallは楽しめない。どちらも、今、公式に無料で提供されているゲームである。また、DOSBoxのようなx86上で動くMS-DOSエミュレーターを使えば、当時とほぼ変わらずに遊べるゲームである。それなのに楽しめない。実に惜しい。

ともかく、最近のゲームのグラフィックの流行は、スクリーンスペースのポストプロセスだろう。なにしろ、どんなシーンでも負荷が予測できる範囲なので、化石並の低スペックなコンソールでも使いやすいのだ。

SSAO(Screen Space Ambient Occlusion)

SSAOは最も有名であろうと思う。Crysis以降、多くのゲームはSSAOを採用した。nVidiaなどは、ドライバー側でSSAOを適用する機能までリリースしたのだ。また、DirectXのラッパーDLLをかませて、既存のゲームにSSAOをかける手法も開発されてきた。Depth Bufferの各ピクセルと、周囲のピクセルの差を比較して、それに応じてやや黒くするポストプロセスである。もちろん、いくらスクリーンスペースと入っても、大まじめに実装しようとするとパフォーマンス上厳しいので、大胆な手抜き方法を使う。見た目に分かりやすい結果としては、面と面が角度をつけて重なり合っているような部分が黒くなる。面白いことに、この効果は、実にうまく人間の脳を騙してくれる。SSAOを古いゲームに適用してみると、急にグラフィックの品質が大幅に向上したように感じる。

ただし、最近は、以前程SSAOが喧伝されなくなっている。代わりに、SSAOっぽい影をテクスチャに最初から書き込んでおく手法もみられる。

ポストプロセスによるアンチエリアス

具体的な名称としては、nVidiaの考案したFXAAが一番有名だが、Crysis 2で使われているSMAA: Enhanced Subpixel Morphological Antialiasingもなかなか面白い。基本的な考え方はどれも同じで、ジャギーをごまかすフィルターである。

そもそも、アンチエリアスの一番分かりやすい目的は、縁のギザギザ、つまりジャギーを目立たなくするというものである。最初に実装されたAAの手法は、目的の解像度より高い解像度で描画して、しかる後に目的の解像度までダウンスケールするというものである。これは原始的だが、最も効果的な方法である。問題は、パフォーマンスが最悪だということだ。今の最新のCPUをつかって、大昔のゲームがやっと動くというほど、パフォーマンス上の問題がある。近代的なゲームに使うことはできない。次に、MSAAというものが実装された。これは、頂点処理だけ高解像度で行い、ピクセルに落としこむ際には、目的の解像度で行うというものである。すくなくとも、ジャギーはだいぶ解消できる。問題は、これも最近のゲームに使うには、ややパフォーマンス上問題がある。

結局、やっていることはジャギーの低減なのだ。ジャギーは縁に発生する。静止画の縁を判定する方法は、大昔から研究されている。だったら、縁を判定して、その部分だけ賢くぼかせば、ジャギーはごまかせるではないか。ということで、FXAAなどのアンチエイリアスは、縁を判定して賢くぼかすピクセルシェーダーのコードで実装されている。

Screen Space Global Illumination、あるいはReal-time Local Reflection

Unreal Engine 3のSamaritanデモで、この技術が披露されている。

また、Crysis 2にDirectX 11パッチを当てると、Real-time Local Reflectionと称して、この技法が使われる。

これも、スクリーンスペースによる反射の実装である。水たまり、テーブル、壁などに、周囲の風景が写り込んでいる。

何にしても、化石スペックのコンソールが足を引っ張りすぎている。テッセレーションを活用したゲームはほとんどない。もっとも、テッセレーションは、その可能性あふれると裏腹に、普通に使っても、それほど見た目にはインパクトがない地味な機能なので、仕方がないのかもしれない。それに、ほとんどのゲームでまともに使っていないので、GPUベンダーもあまり力を入れていないのだと思う。ただし、将来に期待できる。個人的には、Normal MappingやBump Mappingには全然感動できないので、Parallax mappingやDisplacement mappingがもっと使われてほしいものだ。

変わり種としては、Rageが上げられる。伝説のプログラマーJohn Carmackは常に変わったことをする人である。ただし、常に主流の技法からは外れているのだ。今回、Carmackがこだわったのは、テクスチャーだ。Rageでは、使い回しのないテクスチャーを実現している。もちろん、テクスチャーの構築には、デカールを使い回しているが、テクスチャ自体はユニークである。Rageのグラフィックは、序盤の廃墟がすばらしい。ただし、ユニークなテクスチャーは、デザイナーにかなりの負担を強いるらしい。プレイ動画をみても、中盤以降はマップの構成が雑になっているし、ついには長いマップ作成を諦めて、狭い部屋に閉じ込めて、周囲から延々と沸く雑魚敵を相手に戦うような演出でごまかしている。残念なことだ。もう一つ残念なことに、テクスチャーを使いまわさなかったせいで、あんなに短いのに、DVD三枚ほどの容量を必要としている。もちろん、PCならばいまどき20GB程度のサイズは問題にならないが、博物館に陳列されるレベルの低スペックな現行コンソールではかなり問題になる。そして、今時Bump Mappingすらないのだ。まあ、個人的にBump Mappingは価値がわからないのでどうでもいいのだが、やはりないと寂しい物がある。Rageは色々と惜しいゲームであった。

2011-12-29

マリオカート7が劣化していた

たまたま、3DSのマリオカート7に触れる機会があったので、遊んでみたのだが、全然面白くなかった。レースゲームなのに疾走感がまるでなかった。

まずグラフィックが糞だ。加速時にFOVを狭めたり、ブラーをかけたりするなど、レースゲームならではの表現手法は、もう考案され尽くしているはずなのに、なぜこの2011年で、こんなにもしょぼい表現なのだろう。それに、マップが無駄に広い気がする。何故こんなに広いのだろうか。こんなに道が広くては、コースアウトして溝に落ちるとかダートに突っ込んで減速するといったスリルを味わえない。ただ惰性で操作しているだけで完走できるヌルい作りになってしまっている。こんなゲームのどこが面白いというのか。

結局、マリオカートというゲームは、スーパーマリオカートでその可能性を示し、マリオカート64で完成されたゲームなのだろう。これ以上何を付け足しても蛇足というものだ。マリオカート7をやるくらいなら、スーパーマリオカートやマリオカート64をやったほうが、よっぽど面白いはずだ。

なぜこうなってしまったのだろう。今や、ポータブルゲーム機ですら、ニンテンドー64をはるかに上回るスペックを持っているのだ。それなのに、なぜ当時よりつまらない劣化続編しか作れないのだろうか。そして不思議なことに、ゲーム市場は、当時よりはるかに大きく、売上本数も増えていることだ。これは一体どういうことだろう。世の中はクソゲーを望んでいるのだろうか。

2011-12-28

Intel、ネットワーク越しに電源を入れる特許を取得

Intel Receives Network-Power-On Patent

Intelが、ネットワーク越しに電源を入れる特許を取得したらしい。はて、そんなのは自明ではないのだろうか。すくなくとも、この特許が出願された2007年以前にも、そんな装置は山ほどあったと思うのだが。

2011-12-27

鬼を笑わせる

今年も残り少なくなってきたところで、鬼を笑わせるような未来予測をしてみたい。ところが、どうも今は、さっぱり希望がでてこない。というのも、PCの進化がどんどん遅くなっているようなきがするのだ。

たとえば、CPUの処理能力は、ここ数年、驚くほどの向上はない。少し向上はしているものの、その向上が目にみえて実感できないのだ。もはや、我々はMP3のエンコード速度を気にする必要はない。ゲームなど、もはやCPU依存ではなく、GPU依存になっている。動画のエンコードでは多少の実感ができるが、やはり一般的とは言いがたい。

GPUはCPUよりまだ希望がある。といっても、今のPCゲームは、低スペックなコンソールに足を引っ張られて、その性能はあまり意味がない。GPGPU(GPUによる汎用コンピューティング)は、あまりにも適用可能な範囲が限定的で、やはり一般人が直接その恩恵に与ることはない。

HDDの容量なんてもはや誰も気にしないし。SSDは値段が下がる程度の予測しかできない。

もうPCの世界からみると、ハードウェアの進化は止まっているも同然なのだ。

ただし、これがスマートフォンになると、かなり未来は明るい。スマートフォンのハードウェアは、年々進化している。もうしばらくすれば、グラフィック性能が現行コンソールに追いつくだろう。その時、果たしてゲームコンソール、すなわちゲーム専用機は、生き残れるだろうか。今より少しグラフィック性能を上げただけでは、果たして差別化出来るだろうか。十分なグラフィック性能をもったスマートフォンを誰もが持っている世界では、ゲーム専用機など無意味である。実はPCすら危うい。もし、ディスプレイとの接続がワイヤレスになれば、果たしてPCは生き残れるのか。

もちろん、無線によるディスプレイ接続は、帯域的にまだ現実的ではないが、いずれ実現されると考えている。鬼が一番笑いそうなのはここだろうか。

ただし、スマートフォンでひとつ気になるのは、自由が全くないということである。PCならば、どのハードウェアを使うか、どのOSを使うか、どのネットワークを使うか、ということは、自由である。ソフトウェアも、様々な配布形態がある。ところが、スマートフォンでは、こうは行かない。ハードウェアとOSは固定されており、ネットワーク提供者も、大抵固定されている。ソフトウェアは統一された唯一の中央マーケットから入手しなければならない。しかも、このマーケットでは、ソフトウェアには事前に検閲が行われているし、遠隔操作によるユーザー側のスマートフォンのソフトウェアの消去も可能なのだ。これはどういうことだ? 今年は1984年か?

PCならば、ハードウェアには様々な標準規格がある。しかし、スマートフォンにはそんなものはない。ハードウェアとOSがセットになったAppleはさておき、androidさえ、ハードウェアの仕様はころころ変わるので、昔のハードウェアに最新のandroid OSを入れるということが困難である。

さらに、特許の問題がある。スマートフォンの世界では、私のコモンセンスで考えるに、自明であるようなアイディアにまで、特許が与えられている。特許はアイディアに与えられるものだっただろうか。ユーザーの利便性と普及を考えれば、機能やデザインを統一するのは理にかなっている。キーボード配列やマウスは、信号は規格化されているし、レイアウトも規格化されている。スマートフォンにはこれがない。みなてんでバラバラに実装し、それぞれ独自発明であるとして特許を取得し、市場原理に則った競争をせずに、特許裁判に明け暮れている。

もし当時、キーボードのレイアウトやマウスの形状、またはその信号方式に、今のように激しく特許を主張し、各社ともてんでバラバラに実装していたとしたら、今日のPCの興隆はあっただろうか。

これをもってこれをおもうに、あと10年ほどは、PCのスマートフォンに対する優位性は揺るがないであろう。PCがはるかに優れているためではなく、スマートフォンが足の引っ張り合いで自爆しているためである。したがって、私は今、スマートフォンについて何か学ぶ必要は一切ないと結論できる。この不自由と特許の問題が解決されてから学んでも遅くはないだろう。

SOPAガキ

Lauren Weinstein's Blog: "SOPA Lad" (The SOPA Song) - With Apologies to Gilbert and Sullivan

またLauren Weinsteinさんか。この人、本当にGilbert and Sullivanが好きなんだな。

元ネタはこれ、When I was a Lad.

2011-12-22

ブログのデザインを変えた

そろそろ、昔のテンプレートでは管理画面がまともに機能しなくなってきたので、仕方なく新しいテンプレートを使うことにした。HTMLの修正による変更はしたものかどうか悩んでいる。

2011-12-21

Winny開発者の金子勇、無罪

著作権侵害を幇助したとの疑いをかけられていたWinny開発者の47氏(最初に2chに開発宣言をしたレス番が47であった)こと金子勇が、無罪になった。当然である。ソフトウェアを開発、公開しただけで犯罪になってはたまらない。

ただし、Winnyはその仕組みからして、問題がある。ネットワーク内にたった一人の著作権侵害ノードがあるだけで、全員が推定著作権侵害になってしまうのだ。

Winnyの機能に、中継というものがある。これは、ファイルをアップロードするノードとダウンロードするノードの間にたってデータを横から横へ流す、いわばプロキシとなる機能である。この中継機能は、ユーザー外としていないデータまで中継する可能性がある。さらに、Winnyはキャッシュという仕組みによって、中継されたデータを保持し、その後も送信可能な状態におく。これが問題となる。

もし、中継機能がなければ、すなわち自分が明示的にダウンロードを選択したデータのみ、アップロードすることになる。これは、取得と公衆送信に、著作権上問題のないデータであれば、全く問題ない。ただし、中継という機能によって、意図しない著作権侵害かもしれないデータをダウンロード、アップロードしてしまう。つまり、Winnyネットワーク上にひとつでも悪意あるノードがいて、その著作権上問題となるデータをダウンロードしようという別のノードがいれば、自分が中継する可能性がある。よって、Winnyネットワーク内にひとつでも悪意あるノードがあれば、全ノードが推定有罪になってしまう。Winnyネットワークへは誰でも参加できるので、当然問題となる。

当時取るべきだった方法は、この問題を認識して、修正するように働きかけることだったのだ。それを、著作権侵害幇助などというどう考えてもおかしい理由で逮捕、起訴して、無罪判決まで七年もかける。問題のソフトウェアは修正されないまま放置されている。Winnyネットワークは中央管理サーバーを持たないので、全世界に核による絨毯爆撃でもしないかぎり、止められはしないというのに。これだから日本からはイノベーションは生まれない。

とはいえ、もし当時逮捕がなかったとしても、Winnyプロトコルが標準規格になるのは無理だっただろう。本当に普及させたいならば、まず仕様を文章で公開し、リファレンス実装をオープンソースで公開すべきだったのだ。まあ、あの当時はまだこの分野の夜明けのようなものだったので、似たようなプロトコルが乱立した。今となっては、Winnyプロトコルは、古びた時代遅れのプロトコルと言わざるを得ない。そもそも、ファイル共有自体に、新鮮な面白みもない。あの当時と比べて、ハードウェアははるかに進化した。ファイル共有程度であれば、別にP2Pを用いなくたっていいのだ。Dropboxのようなサービスが、当時よりはるかに安価で提供されている。もっとも、日本ではオンラインストレージは違法だというトンデモ判決がでているのだが。

では、今注目すべき技術は何かというと、やはりNamecoinだろう。合衆国でSOPAが議論されている今、中央管理のDNSへの信頼性が揺らいでいる。本来、名前解決のサービスに検閲や規制などがあってはならないのだ。名前解決というのは、著作権侵害や犯罪とは何の関係もないからだ。Namecoinは、ドメイン名の名前解決を、Bitcoinと同じ方法で行うものである。すなわち、P2Pで中央管理サーバーを持たず、信頼性が計算力により保証されたシステムである。

2011-12-05

Safari for Windowsの日本語版の使用許諾書がひどい

Safari for Windowsをインストールしようとして、使用許諾書を読んだところ、ひどい誤訳だらけで、何の意味もなしていないことを発見した。

たとえば、以下のような文面がある。

重要な通知: このソフトウェアがマテリアルを複製するための範囲において、使用することができます。

これを素直に解釈すると、ユーザーである私は、このソフトウェアであるSafariを使って、自由にマテリアル(?)を複製して良い、と読める。

さっぱり理解出来ないので、英語版のライセンスを読んだところ、以下のようになっていた。

IMPORTANT NOTE: To the extent that this software may be used to reproduce materials, it is licensed to you only for reproduction of non-copyrighted materials, materials in which you own the copyright, or materials you are authorized or legally permitted to reproduce.

これは分かりやすい。この文章の意図は、「このソフトウェアは、著作物を複製する可能性がある」と警告しているのだ。翻訳では、文章の途中でぶった切ってしまっているので、訳のわからないものになっているのだ。一体どこの馬の骨が、materialをマテリアルと翻訳して、しかも具体的な定義を与えないことが、いいアイディアだと考えたのだろうか。英語におけるmaterialは改めて定義する必要がない法律用語であったとしても、日本語における「マテリアル」は、そうではない。

しかし、最も問題なのは、以下の文章だ。

2.許諾された使用方法およびその制限
A. 本契約の規定に従い、お客様は、一回につき一台のApple商標が付されたコンピュータにAppleソフトウェアを1部インストールし、使用するための限定的な非独占的ライセンスを付与されます。

Apple商標が付されたコンピュータ? それはつまり、Appleが販売しているコンピューターのことであろう。しかし、このAppleソフトウェアは、Safari for Windowsである。私のコンピューターは、Appleが販売しているコンピューターではない。とすると、私はSafariの使用許諾の条件を満たしていないことになる。この条件を満たすユーザーとは、Boot CampでWindowsを使っているユーザーに限定されてしまう。

ちなみに、原文では以下のようになっている。

2. Permitted License Uses and Restrictions.
A. Subject to the terms and conditions of this License you are granted a limited non-exclusive license to install and use one copy of the Apple Software on each computer owned or controlled by you.

Apple商標が付されたコンピューターなどという文面はない。

2011-11-26

JavaScriptの難読化におすすめのサービス

aaencode - Encode any JavaScript program to Japanese style emoticons (^_^)

alert("Hello, JavaScript")

という何の変哲もないJavaScriptのコードが、

゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

という、訳のわからないコードに変換される。

2011-11-22

2011-11-19

信じられん

この工作精度はすごい。

2011-11-17

Windowsに日本の歴史的な年号を追加する方法

Extending the Windows Japanese Calendar Era information. - I'm not a Klingon

Windows 7/8ならば、レジストリに追加することで、日本の歴史的な年号を追加することができる。

もっとも、年号などいいかげんに滅びるべきである。我々はある時間を起点として線形にインクリメントされていく年号を採用すべきなのだ。年号に対する個人的な反対運動として、私は今年が平成何年であるかを覚えるのをやめている。

しかし、英語の月は数字を使っていないので、日本語と英語に関して言えば、日本が致命傷で引き分けといえるだろう。

2011-11-10

Skyrimのデザインについて思う

Skyrimの発売まで、間近になっている。まだ発売されていないとはいえ、Skyrimの内容については、事前の発表でだいたい明らかになっている。それをまとめているWikiも存在する。

Skyrim:Skyrim - UESPWiki

この情報を元に、Skyrimについて考察しようと思う。

Skyrimは、明らかに複雑性を減らす努力をしている。たとえば、Oblivionでは、八つの基本能力、Strength, Endurance, Intelligence, Willpower, Agility, Speed, Personality, Luckがあった。Health, Magicka, Fatigueなどは、これらの能力とレベルアップによる加算によって計算される従属的な能力であった。さらに、剣の威力は、剣自体の強さが、基本能力StrengthとLuck、スキルBladeによって修正された値であった。だいぶ複雑である。

Skyrimでは、この仕組が、だいぶ単純化されている。Skyrimにおける基本能力は三つ、Health, Magicka, Staminaだけである。もうStrengthやLuckは存在しないので、剣の威力は、単にOne-Handedによって修正されるだけである。

私は、この複雑性を下げることが、快適なゲームプレイにつながると思っている。かつてのゲームは、もっと複雑だったのだ。たとえば、Daggerfallでは、走る、泳ぐ、壁を登る、ジャンプするなどといった動作にそれぞれ独立したスキルが存在したし、避けるだとかクリティカルだとかいうスキルもあったし、ある種の敵と友好的になれるスキルもあった。これは、当時はハードの制約で、複雑性を誇れるものが、結局これぐらいしかなかったのである。

今や、ハードは素晴らしく進化した。リアルタイムなシェーダーによる3Dレンダリング、プロシージャルアニメーション、フルボイスは、全く珍しくない。とすれば、複雑性は、このような数値で実現する必要はないのだ。もっと別方法でいくらでも実現できる。

たとえば、MorrowindにあったMark/RecallやLevitationは、存在しない。これはべつに、技術上の問題ではない、自由にワープできたり空を飛べたりすると、ゲーム制作が非常に制限される。あらゆるダンジョンやらクエストは、ワープや飛行の存在を前提に設計しなければならない。聞説、Morrowindでは多くのクエストのアイディアが、「オゥイェア、そんなのレビテーションで切り抜けりゃいいじゃんHAHAHA」などというスタッフのツッコミによって、断念せざるを得なかったらしい。

興味深い話

The assault on Los Alamos National Laboratory: A drama in three acts

まあ、一言で言うなら、お役所仕事。

2011-11-08

うおおおお!

Twitter / @Flast_RO: キターーーーーーー喜べ野郎ども!!!!
Bug 45114 – implement C++0x alias-declaration

キタ━━━━(゚∀゚)━━━━!!

どうやら、Template Aliasまで含んでいるらしい。

JoystickAPIが欲しい

JoystickAPI - MozillaWiki

これは是非とも欲しい機能だ。これさえあれば、もうゲームのプラットフォームはブラウザだけで完結できることになる。

TPPへの反対を表明する

The complete Feb 10, 2011 text of the US proposal for the TPP IPR chapter | Knowledge Ecology International

5. Each Party shall provide that, where the term of protection of a work (including a photographic work), performance, or phonogram is to be calculated:

  • (a) on the basis of the life of a natural person, the term shall be not less than the life of the author and 70 years after the author’s death; and

  • (b) on a basis other than the life of a natural person, the term shall be:

    • (i) not less than 95 years from the end of the calendar year of the first authorized publication of the work, performance, or phonogram, or

    • (ii) failing such authorized publication within 25 years from the creation of the work, performance, or phonogram, not less than 120 years from the end of the calendar year of the creation of the work, performance, or phonogram.

アメリカの壊れた著作権法を押し付けられるいわれはない。これ以上著作権の保護期間を延ばす必要はない。今保護期間が延びるということは、将来も延びる可能性があるということだ。つまりそれは、著作権は永続するも同義である。

結局、戦前の死後30年の保護期間は、妥当だったはずだ。

2011-11-03

Skyrimがやりたい

Skyrimがやりたいが、やれない。

Skyrimがそろそろ発売される。もっとも、日本では12月まで待たなければならない。Bethesda公式ブログで11.11.11ワールドワイドなどと宣っているが、真っ赤な嘘である。

Skyrimは是非ともプレイしたいゲームだ。しかし、残念ながら、今プレイするわけにはいかない。金がないのだ。Skyrim自体はSteamで$59.99だが、Skyrimをプレイするためには、新しいGPUが必要である。まあ、GTX560あたりを買うと考えても、やはりしめてニ万はかかるであろう。

金のないだけが問題ではない。Skyrimはキリのないゲームである。まともに遊ぼうとすると、恐らく一年ほど飽きがこないであろう。当然、C++本の執筆にも差し支える。他の凡ゲーならば、せいぜい十数時間もあれば飽きてしまうから、まあ、息抜きに遊んでも、特に問題はない。ただし、Skyrimだけは別物なのだ。疑うことなく約束された神ゲーである。

まあ、どうせBethesdaのことだから、見切り発車で発売してバグだらけ、パッチに半年は待たなければならないだろうし、DLCもいくつか出るだろうし、MODも揃ってから遊んだほうが便利だが、やはり神ゲーを遊べないのはつらい。

思えば、今年は大作が多かった。それにもかかわらず、去年と今年は、一切ゲームをしていない。もちろん、すべて遊ぶ価値のないクソゲーだったからだ。もっとも、実際にプレイしたわけではなく、レビューやプレイ動画を見ての感想だから、所詮は動画評論家のそしりを免れないが、それでも、みているだけでつまらなそうなゲームは、実際つまらないに違いない。

まずBulletstormだ。これは、Trailerを見ると、面白そうだった。それに、Duty Callsというパロディゲームをマーケティング用に出したのも興味深かった。

ただし、実際のゲームは振るわなかった。つまらない単調な一本道ゲームだった。しかも、最後は続編を匂わせるクリフハンガーで終わるという、真につまらないゲームだった。

お次はCrysis 2だ。いや、Crysis 2に限って言えば、クソゲーというほどひどかったわけではない。ただ、どこにでもあるような平凡なゲームだったのだ。グラフィックはそれなりによかったが、戦略のカケラもない一本道ゲームだった。まあ、戦略はあった。Cloakで殆どの敵はやり過ごせるのだから。これまた、クリフハンガー的な終わり方をするプロットだった。まあ、確かにブランドは大事だが、露骨にクリフハンガーにしても面白いわけがない。思うに、Crysis 2はゲームなどではなく、CryEngine 3の技術デモだったのではあるまいか。それぐらい、ゲームらしくないゲームだった。

さて、いよいよDuke Nukem Foreverだ。最も、最近の若いもんはDuke Nukemもしらんじゃろうが、かつては伝説のゲームだったのじゃて。DNFが発売されてしまったのは、真に残念なことだった。夢は夢として、いつまでも夢見ていたほうが幸せなのだ。現実は常に夢よりクソである。Duke Nukem Foreverは、5年前に発売したならば、まあ、そこそこなゲームだったに違いない。クソゲーなことには変わりないが、まあ当時の水準ならば、普通以下程度の評価は得られたに違いない。今となっては・・・いや、よそう。もう何も言うまい。

Rageである。Rageも長い間開発していたゲームだった。Doom 3は真っ暗なゲームだった。私が思うに、Doom 3は全ピクセルに黒をアルファブレンドすれば、もっとも効率よく実装できたのではあるまいか。それぐらい暗かった。それはさておき、伝説のゲーム開発会社idと、伝説のゲームプログラマーJohn Carmackの送る最新ゲームRageは、非常に期待されていた。思うに、我々はRageを過剰に期待しすぎていたのではないだろうか。それも無理はない。何しろ、2008年のE3におけるTrailerが、今から見ると詐欺臭いほどのクオリティだったからだ。

これをみれば、過剰に期待するのも当然である。結果は散々だった。メガテクスチャーは20GBもの容量を使い、しかも視点を動かすだけで貼り遅れるという散々な出来であった。しかもボケボケで見るに耐えない。オープンワールドでもないのに、無駄に車や移動といった要素がある。聞説、FPS部分はよくできていたらしい。もっとも、頻繁に移動しなければならないが苦痛だったらしいが。それでも、プレイ時間はたったの十数時間と聞く。プロットなどあってないようなもの。エンディングもエンディングのようには感じられない。何もかもが中途半端なのだ。クリフハンガーですらないのだ。ひょっとしたら、もうこれ以上収集がつかなくなり、とりあえず開発資金を回収しようと、無理やり出荷したのではあるまいか。実際、開発に相当の金がかかっているはずである。最後はBethesdaに身売りまでしたのだから。

こうしてみると、今年は遊ぶべきゲームが一切なかったのだ。Skyrimは約束された神ゲーなので大丈夫だろうとは思う。遊べないのが本当に残念だ。

実は、今年はまだ、もう一本、大作(?)が控えている。Postal 3である。Postal 3も、DNFやRageに引けを取らないほど長く開発されているゲームである。何しろ土台がSourceエンジンなのだ。前作のPostal 2が神ゲーであったことは、議論の余地がない。しかし、長年の延期の末に、ようやくだして、果たして面白いものかどうか。その辺は疑問である。

2011-10-30

Dartにおける代入可能について

まず最初に英語で書いてから日本に訳すという方法で書いてみた。何か違いが出るだろうか。

Dartはoptional typeを採用している。ある変数に代入できない型を代入しようとした場合、静的型警告が発せられる。ただし、プロダクションモードで実行された場合は、実行に何の影響も及ぼさない。

int x = "hello" ; // static type warning

では、代入可能とは一体何か。どのように定義されているのか。13.4 Interface Typesで定義されている。

型Tが型Sに代入可能である場合、すなわち、s = t でtの型がTでありsの型がSである場合というのは、

  • TはSである。

    int s = 0 ;
    

    これは当然だ。.

  • Tはnullである。

    int s1 = null ;
    

    nullは、⊥という特別な型を持っている。これは、どんな型にも代入可能である。

  • TかS、あるいはその両方がDynamicであるとき。

    void main()
    {
        var s1 = 0 ; 
        s1 = 0.0 ; 
        s1 = "hello" ;
    
        var d = 0 ;
        double s2 = d ;
    }
    

    動的型intを持つdを静的型doubleを持つs2に代入しているが、これは代入可能である。したがって、static type warningは発せられない。確かに、実行時には型の不一致を起こすが、それは実行時にしか分からないので、静的警告は発しようがない。

  • SとTがジェネリック型I<...>であり、Tの型パラメーターが、それぞれSの対応する型パラメーターに代入可能な時。

    void main()
    {
        List<int> = <int>[] ;
        List<num> = <int>[] ;
        List = [ ] ; // List<Dynamic>
    }
    

Assignable in Dart

Dart use the optional type. When you assigned to a variable and it isn't assignable, a static type warning is issued. If the code is executed under the production mode, it doesn't affect run time behavior.

int x = "hello" ; // static type warning

So, what exactly is assignable? How is it defined? It's defined in 13.4 Interface Types.

A type T may be assigned to a type S, that is s = t where the type of t is T and the type of s is S, if

  • T is S

    int s = 0 ;
    

    This is obvious.

  • T is null

    int s1 = null ;
    

    null has the special type ⊥. It can be assigned to any type.

  • T or S(or both) are Dynamic.

    void main()
    {
        var s1 = 0 ; 
        s1 = 0.0 ; 
        s1 = "hello" ;
    
        var d = 0 ;
        double s2 = d ;
    }
    

    Notice assigning d(dynamic type of int) to s2(static type of double) is not a static type warning although it is incorrect in run-time. This is because it's assignable. If either T or S are Dynamic, it can't be determined in compile time. So it makes sense.

  • if S and T is a generic type of I<...> and T's type parameters are assignable to S's corresponding type parameters.

    void main()
    {
        List<int> = <int>[] ;
        List<num> = <int>[] ;
        List = [ ] ; // List<Dynamic>
    }
    

2011-10-28

What is it like buying a PC game in Japan?

Today, I saw kotaku used an interesting metaphor to describe what is it like buying a PC game.
If Haruki Murakami's New Book Were Sold Like a Video Game

I think buying a PC game from Japan is also interesting to write about. Even without the metapher.

It started in January...

January
I've heard a famous game developer will release a new game in June. Wow that's too soon. I must pre-order it immediately. But I wonder where to buy it. And the most important thing is, is there a Japanese translation available?

February
It appears the game requires Steam activation. So the package means nothing. I don't need some junk toys they'll include in the package. I wonder who want that crap. I can't understand what Americans are thinking. Anyway, I pre-order it in so called Steam. It allows me to download a game. That's nice. The Japanese Steam listed it up and allows me to pre-order. So it should work. And I've heard they'll release console version of this game in Japan. So naturally, PC version must have Japanese translation.

March
They announced that Japanese translation will be released in August. Well, that's okay. I guess translation need some time. I've also heard they even translate the voice. That's fine. Perhaps I should try English version while waiting. It's completely incomprehensible for me. But who needs story in game anyway? This is not a dull linear JRPG. That's why I'll buy it. I'm so sick of crappy JRPG. Look at the world. Think globally. I can look up words from dictionary if I have to. I'll enjoy the combat in the English version. Then, I'll enjoy the story later in the Japanese version.

April
What Steam? What do you mean I can't buy it from the current location? I am Japanese and sure I live in Japan. Yes I know this is the English version. I want to play regardless and I'm willing to pay. Why don't you let me buy it? Don't you want my goddamn money? This is stupid. I can't understand it. I don't care how much you charge me. I've read from the online forum that we can bypass that check by using what they call it VPN or whatever. I don't know how that works. Also, there are pirates as usual. But I'm not one of them. Besides, I don't know how to pirate a game.

June
At last. The English version is released. I think some people who used VPN will write something in forum. I should better check it... What? Not only they play it today, But they play it in Japanese? How could that even be possible? Well, come to think of it, console game will be released in a few days. So technically, translation works must have been finished already. So what is the point of delay? Why do I have to wait two months!

July
Wow. This is hilarious. They said Steam deleted Japanese translation from their disks. Apparently, It wasn't supposed to be released. But why. Just release the Japanese version already. I don't want to wait any more. Also, why do they allowed to delete files in our disks? I don't understand.

August
What is this? What the FUCK is this? They said they'll delay the release until next year. No. Seriously. That can't be possible. I have enough of this Steam.

2011-10-22

Dartがダウンキャストに警告を出さない理由

Dartでは、ダウンキャストには警告を発しない。

class S { }
class T extends S { }

void main()
{
    S s = new T() ; // アップキャスト
    T t = new S() ; // ダウンキャスト
}

この例では、静的型Tの変数tに対して、静的型Sで、実際の型もSのインスタンスを束縛させているが、これは警告を発しない。アップキャストに警告を発しないというのは自然だが、ダウンキャストに警告を発しないというのは、オブジェクト指向に馴染みのない人からすれば、不思議に思われるかも知れない。現にこの場合、実際の型はTではないのだから、この場合に限っていえば、エラーである。しかし、これは正しい挙動である。では、なぜ警告を発しないのか。

なぜならば、規格に明確に書かれている挙動だからである(13.4 Interface Types)。クラスは暗黙のインターフェースを持つので、この項目はクラスにも適用される。

規格で定義されているとしても、理由はなぜか。それは、Dartの型システムは、ほぼ確実に間違いであろうと思われるコードを見つけるためにあるからだ。間違いである可能性があっても、正当なコードである可能性もあるコードに対しては、警告を発しない。

ダウンキャストは、オブジェクト指向言語ならば、当然行うことである。

class S { }
class T extends S { }

void main()
{
    S s = new T() ; // アップキャスト
    T t = s ; // ダウンキャスト
}

これは、正しいコードである。変数sに束縛されているインスタンスの型は、まぎれもなくTである。したがって、このダウンキャストは正しい。もしこのコードに警告が発せられるとするならば、それは誤りである。このコードに警告を発するようでは、プログラマーは警告というものを信用しなくなってしまう。警告というのは、ほぼ確実に誤りである場合にのみ発せられるべきなのだ。

SとかTなどのやや抽象的な話ではわかりにくい人もいるかも知れない。もっと具体的な話をしよう。Dartではすべてのクラスは暗黙にObjectのサブクラスである。以下のコードは当然動くべきである。

void main()
{
    Object obj = "hello" ;
    String str = obj ; 
}

明らかに、このコードは正しいコードである。

2011-10-21

Bitcoinについて

Coding Horror: Multiple Video Cardsが、Bitcoinのお陰で中古GPUを格安で手に入れられたと書いていたので、Bitcoinの歴史と現状をまとめて見ることにした。

そもそも、諸君はBitcoinを知っているだろうか。いや、知らなくても無理はない。日本では、あまり有名ではないように思う。だから、まずBitcoinとは何かという説明をしようと思う。

Bitcoinとは、演算保証によって信頼を得ている貨幣である。およそ、貨幣というものが広く一般に使われるには、貨幣に対する何らかの信頼が必要である。たとえば、貨幣が金と交換できる保証であるとか、国による保証などといった、信頼が必要である。そのような強い保証のない貨幣は、広く信頼を得ることができず、一般に普及することはない。

Bitcoinは、P2P技術によって実装されたオンライン上の仮想貨幣である。すべての貨幣のやり取りはP2Pによる演算で処理され、個々の貨幣のやり取りは匿名で行うことができる。と、こう書いただけでは、信用のカケラも存在しない貨幣のように思われる。金と交換できず、国家の保証もない貨幣が、どうして信頼できるというのか。だいたい、どうやって偽造を防ぐのだ。それは、演算力である。

Bitcoinを得るには、演算をする必要がある。それも、かなりの演算が必要である。Bitcoinの貨幣のやり取りをP2P上で信頼できるほどに処理するには、暗号を使わなければならない。この暗号処理には、かなりの演算力を必要とする。Bitcoinを得るには、オンライン上でのbitcoinのやり取りに必要な演算の一部を負担する必要がある。すると、Bitcoinを不正に入手するというのは、つまりは暗号を解読するということである。それには、Bitcoinを普通の方法で得るより、はるかに高い演算力を必要とする。このため、Bitcoinの偽造は割にあわないということになる。ただし、誰かがSHA256の画期的な脆弱性を発見した場合は、この限りではない。Bitcoinネットワークを攻撃するには、Bitcoinネットワーク全体の演算力を上回る演算力が必要である。その演算力は、現在のBitcoinネットワークの規模から考えて、現実的ではない。

つまり、Bitcoinの信頼は、演算力とSHA256の暗号強度に依存しているといえる。金銀に交換することはできず、国家の保証もないとはいえ、不正ができないという点で、信頼を得ているのである。

Bitcoinの他の利点としては、国家の影響を受けないということと、プライバシーを守れるということである。国家が貨幣を管理していると、意図的に貨幣の価値を上下させられる可能性がある。Bitcoinの価値は、ユーザーが決定する。そのような中央の権威の影響は受けない。プライバシーというのは、貨幣の動きを特定されないということである。これは、ともすれば麻薬取引などの違法な売買や、脱税などの金銭の動きにも使われがちであるが、それは、別にBitcoinに限った話ではなく、金銀や紙幣でも同じなので、Bitcoin特有の問題というわけでもない。

では、Bitcoinの作者は誰か。これが、どうも怪しいのだ。もちろん、記録は残っている。2008年にSatoshi Nakamotoと名乗る自称日本人によって、Bitcoinの理論と仕様を説明する論文が発表された。最初の実装も、彼によって書かれた。しかし、彼は一言も日本語を発していないし、実装にも日本語は一切使われていない。彼の2010年以降の消息は不明である。彼のメールアドレスは、無料のメールサービスを利用しており、すべての接続は、Tor経由で行われていた。つまり、彼はありとあらゆる方法を使って、匿名性を保つ努力をしていたのである。日本人を自称したのも、事によると、正体を隠すための方便だったのかもしれないとまで言われている。

なんにせよ、Bitcoinの仕組み自体には、未だに脆弱性が見つかっていないし、Bitcoinで使う有名な暗号、SHA256も、未だに画期的な脆弱性は見つかっていない。

さて、Bitcoinは不正が難しいので、最低限の信頼性を備えていることは分かった。Bitcoinの仕様はすべて公開されており、オリジナルの実装以外にも、いくつかの別の実装がでてきた。とくに興味深いのは、演算にGPUを利用した実装である。GPUはCPUほど汎用的ではないが、うまく使えば、CPU以上の演算力を発揮できる。このため、Bitcoin mining(Bitcoin炭鉱業)と呼ばれる、いわばゴールドラッシュのような現象が起きた。高価なGPUが、Bitcoinを稼ぐために多数売れたのである。

Bitcoinはその期待によって、現実の貨幣(例えば米ドル)と交換する所が現れた。その交換レートが高かったので、高価なGPUと電気代を差し引いても、利益が出せたのである。

しかし、ゴールドラッシュが長く続くわけがない。Bitcoinはその多大な期待によって、実価値以上に高い交換レートで、現実の貨幣と交換されてきた。今や、そのバブルがはじけて、Bitcoinの現実貨幣に対する交換レートは暴落し、Bitcoin炭鉱業は以前ほど儲からなくなってしまった。国家や中央銀行のように、貨幣の価値を一定に保つ権威が存在しないのだから、これは当然である。ゴールドラッシュで儲けたのは、シャベルとツルハシを売っていた者であるというのはよく言ったものだ。ハイエンドGPUが山ほど売れたのだ。

そのため、ハイエンドGPUが中古市場に溢れ、冒頭でも言ったように、Jeff Atwoodとかのゲーマーがその恩恵を受けている。

もちろん、これはBitcoinの為替が適正なレートに下がっただけであり、Bitcoinの暗号自体は、未だに破られていない。

Bitcoinの合法性であるが、独自通貨の発行が合法かどうかということにかかっている。これは、国ごとに違うので、なんとも言えない。ただし、オンラインでの売買の興隆をみれば、独自通貨の発行自体は、将来的には大抵の国で合法になる方向に動くだろう。さもなければ、ゲームやPaypalのようなサービスが成り立たない。

私自身はBitcoinには興味がなかったのだが、知り合いに、Bitcoinの仕組みに共感し、自分でも実装を書き、ハイエンドGPUでせっせと掘っている人物がいるので、近況を聞いてみた。彼は、単に技術的な好奇心のためにやっているのであって、小遣い程度の金には興味がなく、したがって、最近のBitcoinと現実貨幣の交換レートの暴落は気にしていないらしい。

私はふと、このBitcoinが、一時期のP2P技術を利用したファイル共有に対する期待に似ているのではないかと思った。あの当時、P2P技術を利用したファイル共有には、なにかゴールドラッシュのような期待があった。確かに、現時点では違法かもしれないが、それは法律が現実に追いついていないだけであって、将来的には素晴らしい可能性を秘めているのではないかという期待があった。

現実としては、法律は一向に変わらず、P2P技術は、Skypeを始めとする通信、ソフトウェアのアップデートの配布などの、裏方技術には使われているが、表立って存在を意識するほどではなくなってしまった。Bitcoinも同じような過剰の期待に押されていたのではないだろうか。

このような意見を、かの知り合いにぶつけてみたところ、彼はこれを認めた。曰く、「たしかに、そういう過剰な期待があるのかもしれない」と。「Bitcoinに触発された後発の仕様もいくつか出ている。Bitcoinは、実際の価値はさておき、コンセプトとして一定の価値があることは確かだろう」とも言っていた。

国家に左右されない貨幣が主流になる時代は来るのだろうか。

アイドック株式会社、紙書籍と電子書籍の抱き合わせ商法を発表

デジタル著作権管理(DRM)ならキーリング|愛読者カード運営代行サービス「i 読(あいどく)」提供開始!!
i読…愛読者カード運営代行サービス
via : これで自炊は不要? 愛読者カード返送者にのみ電子書籍を配信する「i読」 -INTERNET Watch

レコードをカセットテープに録音する? おいおい、何言ってやんでぇ。そんなのオイラの目の黒いうちゃぁ許しちゃおけねぇよ。レコード針やターンテーブルの生産会社が潰れちまうだろうがよ。代わりにこれ、レコードを買うと録音したカセットテープをプレゼント。あ、ほら、もう録音なんてする必要がねぇってもんだ。これにて一件落着。あっぱれあっぱれ。

DTP? よしてくれよ、写植職人が路頭に迷うぞ。最低限でもだな、今の写植と同じ仕組みでなければな。もちろん操作方法も同じだ。

活版印刷? おいおい、版木職人を飢え死にさせる気か? まあ仕方がないから、版木本を買えば、活字本もおまけしてやろうじゃないかい。

版木? そんなの許しちゃおけねぇ。真の書というものはよく手書く者によって写されるべきなんだよ。このままだと、写本職人が失業するだろうがよ。そこでこれ、写本を買うともれなく版木本をプレゼント。

紙? おいおいバカ言っちゃいけねぇや。日常の文章は木簡や竹簡に書いて、高級な文章は絹に書くのが常識だろうがよ。紙なんていう最近できたもんに字なんか書けるかってんだ。

字? おまえなぁ、生きておる智慧が、字などという死物に書きとどめられるはずがない。絵にならまだしも画けようが。それより口伝の続きじゃ。さて我がご先祖は~、怨敵をことごとく討ち平らげ~、この地に来たりて安住し~。さあ覚えるんじゃ。

2011-10-19

Dartで誤って無限ループに陥るコード

Dartは非常にシンプルな言語であるが、恐らく初心者が、誤って無限ループに陥ると思われる箇所がいくつかある。

ファクトリーコンストラクター

class X
{
    factory X() =>  new X() ; // 無限ループ
} 

void main()
{
    X x = new X() ;
}

このコードは、無限ループに陥る。なぜならば、new X()というのは、ファクトリーコンストラクターXを呼び出す式である。これは、つまり自分自身を再帰呼び出ししていることになる。結果として、無限ループになる。

正しいファクトリーコンストラクターの書き方は、別のコンストラクターを呼び出すものである。

class X
{
    X.internal() { }
    factory X() => new X.internal() ;
}

クラスのゲッターとセッター

クラスのゲッターとセッターは、クラスの変数への簡単な読み書きを提供するための特殊なメソッドである。これは、暗黙に生成される。

class X
{
    int val = 0 ;
// 以下のようなゲッターとセッターが暗黙的に生成される
    // int get val() => val ;
    // void set val( int value ) { val = value ; }
}

void main()
{
    X x = new X() ;
    x.val ; // ゲッター呼び出し
    x.val = 0 ; // セッター呼び出し
}

ご覧のように、セッターとゲッターは関数であるが、特別な文法で呼び出すことができるのだ。

サブクラスでは、この暗黙のゲッターとセッターをオーバーライドすることができる。つまり、ゲッターとセッターで、なにか複雑な処理を行うこともできるのだ。

class X { int val = 0 ; }
class Y extends X
{
    int get val() => val ; // 無限ループ
}

これは無限ループとなる。なぜか。考えてみて欲しい、クラスYのスコープにおけるvalとは何なのか。それは、もちろんYのスコープで宣言されているvalである。つまり、Yのゲッター関数valということになる。これは、自分自身の再帰呼び出しである。つまり、無限ループになる。

正しいサブクラスによるゲッターとセッターのオーバーライドは、スーパークラスのゲッターとセッターを呼び出すものである。

class X { int val = 0 ; }
class Y extends X
{
    int get val() => super.val ;
 
}

これで、再帰呼び出しは起こらない。

ちなみにいうと、ゲッターとセッターはトップレベル関数でも使える。

int _val = 0 ;

int get val()
{
    print("このままでは菌類が死滅してしまう") ;
    return _val ;
}

void set val( int value )
{
    print("勉強でも仕事でも 楽しんでやったものが、一番自分の力になるものさ。") ;
    _val = value ;
}

void main()
{
    int x = val ;
    val = 1 ;
}

ChromeがText-to-Speech APIを提供

Chromium Blog: New Text-to-Speech API for Chrome extensions

Chromeがエクステンション向けにText-to-Speech APIを提供するらしい。これは面白そうだ。

2011-10-18

Dartの興味深い機能

named parameterとnamed argument

void f( int x, [ int y = 0, int z = 0 ] ) { }

void main()
{
    f( 0 ) ; // f( 0, 0, 0 )
    f( 0, 1 ) ; // f( 0, 1, 0 ) 
    f( 0, z : 1 ) ; // f( 0, 0, 1 ) 
}

まあ、コードを読めば一目瞭然の機能だろう。省略可能なのは、named parameterだけである。名前を指定できるのも、named parameterだけである。normalFormalParameterは省略も名前指定もできない。

noSuchMethod

class X
{
    void noSuchMethod( String function_name, List args )
    {
        print("$function_name") ;
        for ( var elem in args )
        { print("$elem") ; }
    }
}

void main()
{
    X x = new X() ;
    // 関数名と実引数が表示される
    x.f() ; 
    x.hoge(1,2,3,4,5) ;
    x.fuga("All base is belong to us.")
}

これは解説が必要だろう。もし、クラスからメソッド名のlookupに失敗した場合、そのクラスからnoSuchMethodという名前のインスタンスメソッドが探され、第一引数としてメソッド名を、第二引数として、実引数のリストを渡し、呼び出されるのだ。もし、noSuchMethodという名前のインスタンスメソッドがなければ、NoSuchMethodExceptionが投げられる。

ということはだ、noSuchMethodというインスタンスメソッドを定義していれば、あたかもoperator .を定義したかのように振る舞うのだ。もちろん、実際にはoperator .はないし、メソッド呼び出しにしか適用できないが、DSLオタクは歓喜するだろう。

typedef

typedef int func_type(int) ;

void f( func_type func )
{
    int x = func( 0 ) ;
}
main()
{
    f( (int x) => x + 1 ) ;
}

typedefは、静的型の別名を定義するための構文である。現在のところ、関数の静的型の別名を定義することしかできない。

これはなぜかというと、関数は、具体的な静的型を直接に指定するのは面倒なのだ。こんなふうになってしまう。

void f( int func(int) ) { }

インターフェースFunctionはあるが、あまりにアバウトすぎる。だから、厳密な静的型を意味する識別子を定義するために、このtypedefが存在する。

べつに、これを使う必要はない。たとえば、varで受けても問題ない。DartはOptional Typeを採用しているからだ。静的型は実行時には、ほとんど意味がない。

量子浮遊

こいつは最高にクールだ。

2011-10-17

さっそくDartの規格上のバグを発見

私の唯一誇れる能力は、読解力である。そのため、私がプログラミング言語の規格を読むのを好むのは、自然なことである。このたび、Dartの規格上のバグを発見した。なかなか笑えるので紹介する。もちろん、実装者にとっては洒落にならないが。

以下のコードは、現行ドラフトの文面に従うと、well-formedなDartコードである。

main()
{
    a : { break a ; }
    b : { continue b ; }
}

なぜかというと、現行のDartのドラフト規格は、ラベル付きのbreak文とcontinue文は、label文の中に入ることができるとされている。ラベル文には、文を書ける。また、ブロック文も文である。よって、Label : { } はwell-formedなDartコードであり、その中でbreakやcontinueを使うのもwell-formedである・・・はずだ。

傑作だったのは、現行の実装が、このコードを実際にコンパイルできてしまうということだ。break文の方は、期待通りに動いた。つまり、

a : { print("before") ; break a ; print("after") ; }

は、beforeを出力する。

continue文の方は、コンパイルは通るが、実行時に、不思議なエラーを吐いて強制終了してしまう。もし規格通りに動いていたならば、無限ループになったはずだ。

この件はすでにバグ報告済みである。