酒井法雄のVBコンプリート
第7回
ネットワーク対応ゲームを作る
前回は、インターネットやイントラネットはWWWだけがすべてではないことを述べ、Visual Basicを使ったプログラミングの部品としてICP(Microsoft Internet ActiveX Control Pack)について紹介した。それを受け、今回は実際にICPを使ったネットワーク対戦ゲームを作ることにしよう。
有限会社イント・ツーワン 酒井
法雄 (E-mail norio@int21.co.jp)
世はまさにインターネット時代だ。Windows用の開発ツールも、Javaに対応するものなどが続々と発表されている。Microsoftとて例外ではない。むしろ、インターネットに出遅れたMicrosoftとしては、徹底してインターネットに対応しようとしている。
しかし、Visual Basic自体はつい最近4.0にバージョンアップされたばかりだ。すでにインターネットに対応し、ActiveXコントロールが作れるというVisual Basic 5.0のアナウンスもあったようだが、今すぐに何かできるというわけではない。
そこで、現状のVisual Basicでもインターネットに対応したアプリケーションを作ることができる部品として、ICPもラインナップされることとなった。
ICPについては、先月に概要をすでに述べたが、基本的にはActiveXコントロール集である。ActiveXコントロールは、OCX、すなわちOLEコントロールの拡張版とも言えるものであり、Visual Basicからでも使うことができる。もちろん、IE 3.0などと組み合わせると、VB Scriptも使った柔軟性のあるプログラミングも可能なのだが、それはあくまでもWWWをメインに考えたときの話だ。Visual Basicならば、単体でも面白いアプリケーションを作ることができる可能性がある。
ICPはインターネット用のカスタムコントロール集であるが、もちろんインターネット技術を使ったネットワークであれば、クローズドなLANやWANでも、もちろんイントラネットでも使うことができる。要はIPに対応していればよいのだ。
なお、原稿執筆時にはICPはβ版がリリースされており、MicrosoftのWWWサーバーなどから無料でダウンロードすることができる。このバージョンのオンラインヘルプは英語であるが、さほど量もないので、がんばれば制覇することができるだろう。
今回は実際にICPを使ったプログラミングをしてみることにしよう。
ICPに含まれるコントロールは、メイルのSMTP、WWWのHTTPやHTMLなど、それぞれが代表的なプロトコルに対応したものとなっている。しかし、こういった上位のプロトコルを使うならば、専用のアプリケーションもすでに豊富にあるし、わざわざVisual Basicで作るほどのことはない。もちろん、WWWとメイル、さらにMDBファイルを使ったデータベースと組み合わせるなどして、独自のシステムを構築するといったことも面白いだろう。
表 ICPのコントロールとサポートするプロトコル
| コントロール | サポートするプロトコル |
| FTP | File Transport Protocol (FTP) |
| HTML | HyperText Transfer Protocol (HTTP) |
| HTTP | HTTP |
| NNTP | Network News Transport Protocol (NNTP) |
| POP | Post Office Protocol, version 3 (POP3) |
| SMTP | Simple Mail Transport Protocol (SMTP) |
| WinSock TCP | Transmission Control Protocol/Internet Protocol (TCP/IP) |
| WinSock UDP | UDP/IP |
しかし、そういった上位のプロトコルより、より下位のTCPやUDPといったプロトコルを使って、独自に上位プロトコルをインプリメントしたほうが自由度は高くなる。もちろん、こうして勝手に作ったプロトコルは一般的なものではないのだから、限られた範囲の中で使うしかない。業務に使うようなものであれば、むしろその方がいいかもしれない。だが、一般にも広く使われるようなプロトコルだって作ることはできる。用途が広く受け入れられそうなものであれば、勝手に作ったプロトコルが世界中に広まるということだって考えられるのである。そう、WWWサーバーやMosaicがフリーで公開された例もある。
今回は、そこまで大きな話をするつもりはないのだが、勝手なプロトコルを作って、とりあえずは社内LANなどで使ってみるというのも一興だ。
そこで、とりあえずはゲームを作ってみることにしよう。いわゆるネットワーク対戦ゲームである。最近では、Windows 95にバンドルされているHeartsはネットワーク対戦できるゲームだし、以前からMS-DOSで作られてきたゲームなどにもネットワーク対戦のゲームも数多い。実は、こうしたゲームの多くはIPXというNovelのプロトコルを使ったものが多かった。それをTCP/IPでも使えるような仕組みとして米国のkaliがある。これはこれでなかなか面白いものなので、興味がある方はWWWサーバーhttp://www.axxis.com/kali/をのぞいてみるといいだろう。
今回は、そういった本格的なゲームを作るほどの時間も体力もデザイン力もないので、比較的カンタンなゲームにしよう。
カンタンといっても、そうそうカンタンにはいかないのがゲームというものだ。プログラミングの中でも、ゲームこそ一番難しいものなのだ。プログラマーの技術力はもちろん、ゲームデザイン、シナリオ、グラフィックデザイン、サウンドといった様々な要素が必要になる。したがって、ゲームはそれなりの人数でチームを組んで作るのがふつうだ。フリーソフトウェアでも、同様のケースが多い。
それらの仕事を一人でこなそうとすれば、当然無理がある。ましてや私にはデザインセンスや音楽のセンスは、自慢じゃないがさっぱりない。もちろん、本格的に売り物として作るのならチームを作るところではあるが、これはあくまでもサンプルであり、ICPを使ってプロトコルを独自に作るデモなのである。では、それらの作業を比較的ラクに一人でこなすことができるようなゲームを考えないとならない。そこで、次のような設計指針を考えた。
1. 誰もがすぐにできるゲーム
これは当然なのだが、あまりにもルールが難しいとプレイするのも大変だ。もちろん、プログラムも大変になる。そこで、誰もが知っているようなゲームをコンピュータでネットワーク対戦できるようにしたい。
2. 対戦できるゲームであること
これまた当然だが、ネットワークで対戦できてこそ意味がある。カードゲームや碁や将棋などだとよさそうだ。シューティング系もなかなか面白そうだ。
3. ユーザーインターフェイスがカンタン
これは、Visual Basicの処理に向いているかというところにも関係するのだが、マウスだけで操作できるような単純なものがよいだろう。
4. Visual Basicの処理に向いていること
Visual Basicは決して高速なものではない。特に4.0になってからは遅くなってしまった。そう考えると、シューティング系などはプログラムの実行速度の点で、ちょっと難しい。カードゲームや碁、将棋などは実行速度の点では問題なさそうだ。インプリメントもやりやすいだろう。
5. グラフィックスのデザインがカンタン
GUIのゲームを作るのだから、多少なりともグラフィックがないことには話にならないし、まさかテキストベースでやるというわけにもいかないだろう。そもそもが、DOSならばANSI.SYSでも入れてあればRougeやNetHack、Hantのようなテキストベースでの疑似グラフィックゲームもできるだろうが、Visual Basicではそういう処理も向いていない。そこで、最低限のグラフィックスで済ませることにしたい。となると、たくさんの種類のカードや駒があるようなものは難しい。もちろんそういったOCXなどもあるのだが、ICP以外のカスタムコントロールは基本的に使わないことにしたい。そうなると、白と黒の二つの駒しかない碁あたりがよさそうだ。
6. 思考アルゴリズムがカンタン
対戦ゲームだから思考アルゴリズムは基本的には必要ない。しかし、上がり判定をする必要がある。囲碁やオセロのようなタイプだと、このへんはちょっと難しそうだ。はさみ将棋とか五目並べのようなものなら大丈夫かもしれない。
7. 対戦相手とチャットもできる
ゲームのプロトコルを作るといっても、実際には文字列を送受信するということになる。そこで、テストのためにもチャットができるようなプログラムを作り、文字列を監視しながらデバッグをしていくとよさそうだ。もちろん、その仕組みを残しておけば、対戦相手とチャットをしながらゲームができる。
8. 対戦のプロトコルがカンタン
ここまでくると、だいたい指針が見えてきた。はさみ将棋や囲碁のような1対1で行えるようなゲームである。しかし、いきなりお互いのプログラムと通信するとなると、拡張性がない。後で、多人数でゲームをするとなると、この仕組みは使えなくなるのだ。また、ゲームを見ているだけの端末というのも作れない。もともと、TCP/IPはコネクションを張らないといけないので、そのあたりの手順も考慮しないといけない。
そこで、ゲームをするクライアントプログラムを作り、すべてのプレイヤーは特定のサーバーに接続することにしよう。これならば、多人数になっても対戦できる。
これで、指針の方向性は決定した。これを元にゲームは次のような概要仕様とすることにしよう。
- 対戦型五目並べを作る
- まずはチャットができるプログラムを作る
- チャットを行うクライアントと、クライアント間の通信を制御するサーバーを作る
- チャットを拡張してゲームに仕上げる
なお、五目並べといっても4.3はだめだとかいろいろローカルルールがある。これには上がり判定が面倒になってしまうので、とにかく5つ並べた方が勝ちということにする。したがって間抜けではあるが、勝負がすでに見えていても5つ並ばないと上がりにならないことにしよう。
まずは、チャットのプログラムを作ることにしよう。ここで使うICPのコントロールは、HTTPやSMTPなどのいわゆるアプリケーション層のものではない。その下位にあたるトランスポート層にあるものである。
表 プロトコルの階層
| アプリケーション層 | HTTP, FTP, SMTPなど |
| プレゼンテーション層 | 圧縮やビットストリーム変換 |
| セッション層 | セッションの確立と継続 |
| トランスポート層 | TCP, UDPなど |
| ネットワーク層 | IP |
| データリンク層 | Ehernet, PPP, Slip, FDDIなど |
| 物理層 | 同軸ケーブル、より対線など |
したがって、TCPかUDPを使うということになる。 TCPは、特定の相手とセッションを張って会話するためのものであり、UDPはある程度不特定の相手にデータを送るものである。したがって、TCPは1対1の通信であり、UDPはラジオやテレビの放送のようなものである。用途によってこれらを使い分ければよい。
ここで作るのはチャットプログラムである。チャットをするクライアントとなるプログラムは、チャット用のサーバーに接続する。接続した同志がサーバーを経由して会話ができるようにするというわけだ。したがって、多人数のチャットであっても、基本的には各クライアント対サーバーという1対1の通信ということになる。したがって、ここで使うコントロールはTCPである。もちろん、UDPを使ってネットワーク上すべてのコンピュータにデータを送りつけることもできるが、これは無駄である。特にインターネット上でこれをやってしまうと、いたずらにあちこちのネットワーク上にパケットが飛ぶことになりかねない。特定の相手方にのみ送るのだから、TCPを使った方がいいのである。
実は、TCPコントロールやUDPコントロールを使ったサンプルプログラムとして、カンタンなチャットプログラムを作成し、これをVisual Basic Magazineに掲載した。したがって、ここでも同様のものである。詳しくはVisual Basic Magazineをご参照いただきたいということで省略したいところなのだが、それではあんまりなので、ここでも概要を述べておこう。
まずは、TCPコントロールのプロパティ、メソッド、イベントを見ていこう。
- TCPコントロールのプロパティ
プロパティ 説明 BytesReceived バッファに溜まっている受信したデータのバイト数 LocalHostName 自分のマシンの名前を得る LocalIP 自分のマシンのIPアドレスを得る LocalPort ローカルマシンのポート RemoteHost リモートマシンの名前あるいはアドレス RemoteHostIP 相手マシンのIPアドレス RemotePort リモートマシンのポート SocketHandle ソケットのハンドル State 接続状態
- TCPコントロールの定数
定数 値 説明 sckClosed 0 Default. Closed sckOpen 1 Open sckListening 2 Listening sckConnectionPending 3 Connection pending sckResolvingHost 4 Resolving host sckHostResolved 5 Host resolved sckConnecting 6 Connecting sckConnected 7 Connected sckClosing 8 Peer is closing the connection sckError 9 Error
- TCPコントロールのメソッド
メソッド 説明 Accept リクエストに応えてコネクションを開始する Close コネクションをクローズする Connect 相手を指定してコネクションを開始する GetData バッファからデータを取り出す Listen ローカルポートで受信待ちを開始する PeekData バッファのデータを見る SendData データを送信する
- TCPコントロールのイベント
イベント 説明 Close コネクションがクローズされた Connect コネクションが開始された ConnectionRequest コネクションリクエストがきた DataArrival データが届いた Error エラーが発生した SendProgress 送信状態を通知する TCPコントロールは、送信も受信もできる。すなわち、これひとつあれば、クライアント側もサーバー側もプログラムを作ることができるわけだ。一般的には、サーバーは常に動いているものであり、クライアント側からのリクエストによってさまざまなサービスを行う。したがって、クライアント側とサーバー側で設定も異なるということになる。次に、TCPコントロールのクライアント側とサーバー側の一般的な設定の手順を示す。
- サーバー側
- LocalPortプロパティでローカルポートを指定する。このポートは、Windows NTであれば、ファイルwinnt/system32/drivers/etc/servicesに記述してあるポートである。Windows 95のときには、windows/servicesである。servicesファイルは修正してポートを独自に追加すべきだが、これは特にしなくても動くことは動く。
- Listenメソッドを指定して受信を開始する
- ConnecttionRequestイベントが発生したら、引数のrequestIDをAcceptメソッドの引数として実行する。
- 必要に応じて、SendDataメソッドで送信する。
- クライアント側
- RemoteHostプロパティでサーバーマシンを指定する。
- RemotePortプロパティでサーバーマシンのポートを指定する。
- Connectメソッドを使ってコネクションリクエストを送る。
- サーバーからAcceptされたら、Connectイベントが発生する。
- 相手からデータが送られてきたら、DataArrivalイベントが発生するので、GetDataメソッドでデータを取り出す。
- Closeメソッドを使ってコネクションを終了する。
サーバー側とクライアント側での対応を見ていけば、そんなに難しいことはないだろう。ここでは単純化してクライアントとサーバーに明確に分けたが、もちろんその両方となるようなプログラムを作ることはできる。また、このままでもクライアント側からデータを送信することもできるし、受信もできる。要するに、クライアントとサーバーの関係というのは、コネクションのリクエストの手順の問題なのである。
実際に、このコントロールを使ってプログラムを作るときに注意が必要なのは、サーバー側でのコントロールの設定である。コネクションのリクエスト待ちのコントロールと、実際に通信をするコントロールは別に用意しなくてはならないのだ。これはコントロール配列として動的に増やしていけば、複数のコネクションを張ることができる。
それでは、さっそくTCPコントロールを使ったチャットプログラムを作ってみよう。チャットをするだけだから、特にアプリケーション層のプロトコルを作る必要はないように思うのだが、そうではない。実際には、誰が書いたものか分かるように、クライアントを見分けるためのハンドルが表示されないといけないし、接続を切るとか、チャットにいる人の一覧を得るとかいう仕組みは必要だ。そこで、ここでもカンタンながらプロトコルは考えないといけない。
クライアントは20001番のポートでサーバーに接続する。サーバーはクライアントに接続許可を出し、さらにハンドル名をリクエストする。ここでは、「TELL_ME_HANDLE」という文字列を送るだけである。これに対応して、クライアント側では「/haハンドル名」という形でハンドルを送る。すると、サーバー側はチャットができるグループにクライアントを追加する。サーバー側を終了すると、クライアント側にすべて通知する仕組みや、クライアント側からコネクションを閉じたときに、他のユーザーに通知する仕組みも入れてみた。この他にも、クライアント側から文字列を送ると、サーバー側で一定の処理をする仕組みをいくつかつけた。「/w」で接続中のユーザー一覧を返す。「/ha」では手動でハンドルを変更することができる。また、BEEPを鳴らすというコマンドもつけてみた。詳細についてはリスト(chatcli.frm, charsvr.frm)を参照されたい。
まずは、五目並べのゲームが成立するためのプロトコルを考えよう。とはいえ、難しいことはない。文字列を決めておくのである。すでにチャットプログラムで作ったように、クライアントとサーバー間でのやりとりを規定する文字列を決めるだけだ。とはいえ、ゲームが成立するための要素を洗い出さないといけない。
ここでは、チャットから含めて次のような流れを考えてみた。ただし、括弧内はTCPで行われる処理である。
チャットクライアント その1
チャットサーバー
★チャットおよび全体のコネクション
| クライアント側 | サーバー側 |
| (接続要求) | (接続許可)、 ハンドルの要求 |
| ハンドルの送信 | 参加者のハンドルを各クライアントに通知 |
| 接続者一覧要求 | 接続者一覧を要求先に通知 |
| 接続者一覧の表示 | |
| ビープサウンドの要求 | クライアントすべてにビープ用文字列を送信 |
| ビープサウンド | |
| (接続終了要求) | (接続終了許可) |
| (接続終了通知の受け取り) | |
| (サーバーのクローズによる接続終了通知) | |
| (接続終了通知の受け取り) |
★ゲーム固有の流れ
| クライアント側 | サーバー側 |
| ゲームへの接続要求 | ゲームへの接続許可または拒否 |
| 許可のときには石の色を通知 | |
| 接続者が2人になったらゲームの開始を通知 | |
| 接続可否の受け取りと結果表示 | |
| 接続許可のとき、石の色を得る | |
| ゲーム開始のとき、自分の石が黒だったらゲームを開始する | |
| 配置した石の位置 | 配置された位置をゲーム参加者全員に通知 |
| 配置された位置を受け取って描画 | |
| 上がり判定処理 | |
| 上がりのときゲームオーバーを通知 | 両者からゲームオーバー通知がきたら、ゲーム開始を通知 |
この仕様はミニマムであり、ゲームを見物する人のことは考えていない。もっと多機能にするためには、さらに拡張する必要がある。ともかく、この流れに合わせて、文字列を決めていけばよい。
ここでは、次のような定数を決め、この標準モジュールファイルをクライアントとサーバー双方で共有するようにした。
| Global Const GETHANDLE = "TELL_ME_HANDLE" |
| Global Const BEEPSOUND = "!BEEP!" |
| Global Const GOMOKU = "!" |
| Global Const ENTERGAME = "ENTERGAME;" |
| Global Const STARTGAME = "STARTGAME;" |
| Global Const GAMEOVER = "GAMEOVER" |
| Global Const DROPSTONE = "DROPSTONE;" |
| Global Const NACK = "NG" |
| Global Const G_BLACK = "BLACK" |
| Global Const G_WHITE = "WHITE" |
この定数と、実際に付加して送られる情報は、次の表のように表される。
★チャットおよび全体のコネクション
| クライアント側 | サーバー側 |
| (接続要求) | (接続許可)、 GETHANDLE |
| /haハンドル | 参加者のハンドルを各クライアントに通知 |
| /w | 接続者一覧を要求先に通知 |
| 接続者一覧の表示 | |
| BEEPSOUND | クライアントすべてにBEEPSOUNDを送信 |
| ビープサウンドの実行 | |
| (接続終了要求) | (接続終了許可) |
| (接続終了通知の受け取り) | |
| (サーバーのクローズによる接続終了通知) | |
| (接続終了通知の受け取り) |
★ゲーム固有の流れ
| クライアント側 | サーバー側 |
| ENTERGAME | ゲームへの接続許可または拒否 |
| G_COLOR;[G_BLACK, G_WHITE] | |
| STARTGAME;相手のハンドル | |
| 接続可否の受け取りと結果表示 | |
| 接続許可のとき、石の色を得る | |
| ゲーム開始のとき、自分の石が黒だったらゲームを開始する | |
| DROPSTONE; X,Y | DROPSTONE;自分のIP;X,Y |
| 配置された位置を受け取って描画 | |
| 上がり判定処理 | |
| GAMEOVER | |
| STARTGAME;相手のハンドル | |
このように、すっきりとプロトコルを決めておかないと、作り始めることはできない。また、基本的な部分さえ押さえて動くようにしておけば、後から拡張するときもたやすい。もちろん、拡張も考えたプロトコルや構造にしておかなくてはいけないのは言うまでもない。
とはいえ、実際にはもっと欲張ってプロトコルを作ってしまい、苦労してデバッグした挙げ句、結局のところつかわなくなった文字列などもあったというのが真実だ。
プロトコルも決定したので、実際に五目並べを作ることにしよう。実は、このプログラムの元は数年前に作った五目並べだ。思えば、こちらの手のうちが相手の画面に表示されないような対戦ゲームを作りたかったのだが、当時はリモートオートメーションもなかったし、これほどネットワーク環境が整うとも思っていなかったこともあり、スタンドアローンで動作する五目並べを作ったのだった。
実際には、このスタンドアローン五目並べを改造してチャットプログラムに付加した形なのだが、ここではその中核となる次の部分について解説しよう。
まず問題になるのが、この手の駒を使ったゲームのインプリメント方法である。というのは、ご存じのようにVisual Basicでは描画するよりコントロール単位で動かした方がプログラミングしやすい。しかし、キャラクターを動かすようなゲームと違って、五目並べではどんどん駒が増えていく。そのたびにコントロール配列をロードして配置していくというのでは、メモリも食ってしまう。ピクチャーやイメージコントロールではなおさらである。また、コントロールにしてしまうとサイズが固定されてしまう。もちろんリサイズすることも可能だが、数十個ものコントロールのリサイズは負荷がかかるばかりだ。
そこで、ここではあらかじめ元となるピクチャーを用意して、それをWindows APIのStretchBltを使って適切な位置に描画することにした。この方法ならば、メモリもさほど食わない。また、描画自体はPaintイベントでまとめておけば、リサイズ時などの再描画もスムーズだ。
また、実際にどの位置に駒があるかは、2次元の配列を持って、その内容に空、黒、白を表す数値を代入することにしよう。
対戦ゲームであるから、ゲームを解く思考アルゴリズムは必要ないが、当たり判定、もとい、上がり判定の思考ルーチンは必要だ。
五目並べでは、5つの同じ色が並んだら上がりである。前述したように、5つ並ぶ前に結果は分かるものなのだが、ここでは単純化している。
上がりの判定は、ひとつひとつの位置について、各方向にスキャンして5つ並んでいるかを判断すればよい。だが、これでは無駄がある。実際には、今置かれた駒の回りをスキャンするだけでよいのだ。したがって、現在位置から各方向について続いている駒があるかを調べればよいということになる。
そこで、ここでは方向を示す連続する定数を決め、各方向ごとにいくつ同じ色が並んでいるかを調べる関数を呼び出すようにした。
こうして、対戦型五目並べを作る準備は整った。あとはインプリメントするだけである。
コネクションなどのチャットの基本的な部分はすでに作ってあるから、ここを拡張してプロトコルをインプリメントすることになる。データの送信はSendDataメソッド、受信はDataArrivalイベントで実現されるから、クライアントとサーバーがそれぞれ対応できるようにコーディングしていけばよい。
こうしてできたクライアント(管理およびチャットウィンドウ、ゲームウィンドウ)、サーバーの各実行画面とコードを示す。
五目並べクライアント 管理&チャットウィンドウ その1
五目並べクライアント 管理&チャットウィンドウ その2
五目並べクライアント ゲームウィンドウ
五目並べサーバー
実行の手順は次のようになる。
- サーバープログラムを起動する
- クライアントのプログラムを起動する。以下、クライアント側での設定をする
- 接続先のサーバーマシンの名前を指定する
- 自分のハンドルを指定する
- <Connect>ボタンを押す
- コネクションが張られると、ステータスラベルにその旨が表示され、チャットテキストボックス中に表示される。
- <Enter Game>ボタンを押すと、ゲームに参加できる。最初に参加した方が黒(先手)になる。
- 二つのクライアント(別々のマシンでないといけない)からゲーム参加があると、ゲームが開始される。
- 五目並べのゲームウィンドウで、打ちたい位置をマウスで左クリックする。これを交互に繰り返す。手順についてはチャットウィンドウの下部ラベルや五目並べウィンドウのタイトルに表示され、自分の番にはビープ音が鳴る。
- どちらかが勝つとゲームは終了し、その旨を通知するメッセージボックスが表示される。両者が<OK>ボタンを押すと、次のゲームが開始される。
といったわけで、なかなか楽しくゲームができる。もっとも、上がり判定が情けないのはやはり気になる。このプログラムには、他にもいくつか問題がある。まず、ゲームだけを終了させる機能がない。また、ゲームは最初に参加したユーザーだけができ、後から他のユーザーに代わることができない。サーバーを一度終了させないといけないので、ずっと走らせておくわけにはいかない。他にも、このコントロール自体がまだ未完成であることもあって、ときどき動作がおかしいと思うこともある。また、エラー時のリトライについてのプロパティなどがないところを見ると、リトライについても本当は自分でやらないといけないようだ。
比較的単純なものではあったが、Visual BasicとICPを使えば、独自のアプリケーション層プロトコルを作り、今まではなかったネットワーク対応アプリケーションを作ることができる。
ここではたまたまゲームであったが、もちろん業務のプログラムを作ってもいい。現在のようにHTTPだけでは限界があるからJavaだとかJava ScriptだとかCGIだとかActiveXだとか話を複雑にする必要はないのだ。このように、実際問題として作りやすく使いやすいものを自由度の高いツールで作った方が、結局のところネットワーク資源の有効活用にもなる。まだまだ細いインターネットで、巨大なヌード画像ばかりではなく、ヘンなプログラムが転送されるなどさせることはないのではないだろうか。
WWWは重要ではあるが、WWWばかりに気を取られていると、おかしなことになりかねない。現に、Netscape 4.0ではマルチウィンドウでの動作や、オーバーラップ可能なフレームがインプリメントされるという情報がある。このようにどんどん複雑になってくると、NCなどのインターネット専用端末とか、家電になるとかいう話から遠ざかりかねないのではないだろうか。それよりは、用途にあった専用のものを作るというのが、業務として使うには向いているように思える。もちろん、そうして作ったプロトコルが世界的に認知されれば、それもいいことに違いない。