デュエルオンライン開発日誌

2004-10-26 iPod miniに応募したいから

Seesaaトラックバックするだけで応募できるというプレゼントに参加したいくて書いているだけだったり。

汁ーんwwwwww汁ーんwwwwww 2009/06/16 08:34
週一ペースしかやってないのに20万振り込まれててぶっちゃけ手震えたww
とりま、あと4人こなしたら単純に100万だし・・・楽勝じゃん?
女の言う通りにマヌコ刺激してあげるだもんなーヽ(´ー`)ノ
俺は自分が気持ちよくないとイヤだから本番もやってるけどねwwwww

http://shiofuki.navi-y.net/8gT8LDS/

えふwwえふwwえふwwwえふwwえふwwえふwww 2009/08/15 01:08
ケイジの奴・・ネットやっててコレ知らないって何なのwwwwww
金に困ってるみたいだから教えてやったらソッコーでヤりやがったしww
てかあいつキモデブなのに何でいきなり8 万貰えてんの???
わけわかんねぇしwwwwwww

http://kachi.strowcrue.net/95HY2eo/

2004-10-24 そろそろネタ切れ?

もっと書くことがあるような気がしていたのだが、意外に思いつかない。忘れているだけか?

アクセス制限の話

どれほど活用されているのか知らないが、サーバにはアクセス制限機能がある。当初はなかったものだが、荒らし行為をする人がいるので追加した機能である。わざわざデュエルオンラインで荒らし行為をする人がいるとはねぇ…

アクセス制限にはその運用上の難しさがあるのだが(どの程度の行為を荒らしとみなし制限をかけていくのか、いつ解除するか等々)、それはおいておいて、ここでは技術的な話だけしておく。

自分のサイト掲示板とか管理したことのある人は知っていると思うけど、通常、アクセス制限は「IPアドレス」か「ホスト名」で行われる(本質的には同じものということで話を進める)。というか、逆にそれら以外に使える情報がない。しかし、これらによる制限に問題が多いことはわざわざ私が言うまでもないくらい周知のことである。

IPアドレスは一定ではなく、相手の接続が変われれば変わることがある。したがって、特定の相手を制限しようとしてもすり抜けられてしまうことが多い。その対策として、制限したい相手の使っているプロバイダーごと制限してしまうという手があるが、それは無関係の人のアクセスまで制限してしまうという問題がある。これIPアドレスを使う限りどうにもならないことである。このため、掲示板で思うようにアクセス制限をかけるのは難しい。

さて、で、私は考えた。デュエルオンラインのサーバアクセス制限はどうするか。IPアドレスは当然わかっているので、それで制限することは簡単だが、それでは上記の問題はそのままである。幸い(?)、サーバに接続するクライアントであるデュエルオンラインも私がつくっているソフトである。ということは、何か相手を特定できる情報デュエルオンラインから送ってやって、それをキーにアクセス制限をかければいいのではないかと考えた。いけそうである。

となると、次の問題は「相手を特定する情報として何を送るか」である。一番最初に思いついたのは「レジストリに何か書いておいて、それを送る」というものである。サーバシリアル番号のようなものを管理して、それを各パソコンレジストリに書いておいて、サーバ接続時に送るというわけである。レジストリが空ならサーバから新しいシリアル番号を与えてやればよい。

発想は良さそうだったが大きな問題があった。「サーバは誰でも立てられる」ということである。これではシリアル番号の管理はできない。それとレジストリをいじることに嫌悪感を抱く人がいることも知っていたので、この案ばボツとなった。

次に考えたのは、パソコンの中から、そのパソコンを特定できるような何らかのシリアル番号のようなものを抽出するというものであった。「そういえばWindowsXPアクティベーションでそんな話を聞いた記憶が」と思い、調べてみると使えそうな情報があることがわかった。そして、その中から比較的簡単に取り出せて、変更が難しい2つの情報を取り出してサーバに送ることにした。それが今のバージョンに入っているものである。何を送っているかはあえて秘密ということで(たいしたものは送ってない)。「プライバシーの侵害」ということを言う人もいるかもしれないけど、そういう人は遠慮なく文句を言って欲しい。

「これで完璧!」というわけではない。今の仕掛けでも知識のある人であればアクセス制限をすり抜けることはできる。少なくとも私は(作者であるということを抜きにしても)技術的にできる。あるいは、無関係の人に制限をかけてしまう可能性も0ではない。

ただ、サーバを管理している人がアクセス制限をかけようと思ったときはIPアドレスホスト名ではなく、サーバのアクセス制限の説明の「謎の文字列」って奴を使った方が精度がいいということは知っておいて欲しい。

2004-08-17 バージョンアップはしたし

バージョンアップも一応、終えたところで、こちらの執筆を再開したい。

カードデータの持ち方

今日も「なぜ、長きにわたり要望されている機能が実現されていないのか?」という疑問に対しす言い訳をしておきたい(←言い訳なのにえらそうに)。

だいたいどのソフトも最初に考えるべきことはデータをどういう構成で持って、どう管理するかという点である。デュエルオンラインにおけるデータとはもちろんカードデータのことである。

フィールドにどんなカードがどんな状態で出ていて、墓地にはどんなカードがあり、手札、デッキには何が入っていて、除外されたカードは何かというものを正確に管理する必要がある。

一番ややこしいのはフィールド上だ。カードの状態がころころ変わるので、そのデータ管理は面倒だ。でも、逆にその分神経質につくってある。そして、問題となったのは手札とデッキである。

私は大きな勘違いをしていた。ルールや効果にまだ詳しくなかった私は「デッキ、手札、墓地に相手のカードが入ることはない」と勘違いしていた。当時、「相手にコントロール奪われたカードをペンソルで手札に戻すと持ち主の手札に戻る」、「コントロールを奪っている相手カードを破壊すると持ち主である相手の墓地に落ちる」というルールがあることから、墓地や手札に相手のカードが入ることはないし、デッキも同様だと勘違いしたのだ。

そこで、私は手札、デッキ、墓地ではカード名だけ覚えておけばよく、その他の情報は記憶しておく必要はない。そして、手札、デッキ、墓地のカードはすべて自分のカードとして処理すれば良いと考えて設計してしまったのだ。

だから、プログラム的には、カードは手札や墓地からフィールドに出たときにようやく名前だけでなく様々な属性を持ったカードデータになる。攻守の変更もできるし、コントローラの変更もできる。しかし、手札、デッキ、墓地では名前以外ことは記憶していないので、他の属性の操作はできない。

したがって、相手のカードを手札に入れたり、デッキに入れることは今でもできない。これは完全に設計ミスである。私が様々なカードの効果を知らなかったことが原因だ。私は「他人のカードを手札やデッキに入れたら、混ざってしまって後で困ることになる。だからまぜることはないはずだ」と勝手に思っていた。そういう意味では遊戯王ルールは私の理解を越えていた。それがいいことだとはあまり思えないのだが。

というわけで、相手のカードを手札やデッキに入れるのが難しいという状況はどうにもならない。データ構造の変更は変更部分が多過ぎて私もどれくらいの作業になるかわからないのだ。

今の枠組みでうまくやるために、カード名に小細工して区別するようにするというのも検討したのだが、いい案は浮かばなかった。本当に申し訳ないと思っている。私がもっと色々なカードの効果さえ知っていれば…

2004-08-13 サーバのバージョンアップをしたところで

頭はサーバモードになっているので、サーバに開発経緯を書いておこうかと思う。開発の順序からいけばかなり後の話なのだが。まあ、通信関係の話の続きとしては悪くないし、何よりあまり気にしないで書きたいことを書くということで。

サーバの開発目的

言うまでもなく、

  1. 対戦の接続を簡単にする
  2. プライベートIP同士の対戦を簡単にする

サーバの開発目的である。個人的には「軽いチャットが欲しかった」というのもあるけど。

とりあえず、1つ目の目的を最初のバージョンで実装した。最初にリリースしたサーバは1日でつくったと言えば、驚いてくれる人はいるだろうか。チャットを接続の自動化だけなら、正直さほど難しくはなかった。前々から構想はあったので、私の頭の中では設計は終わっていたし。

「接続を簡単にするのは、独自にサーバを立ち上げない限りどうにもならない」という思いは開発当初からあったことで、それを実装しただけだった。IGMなんていうものもあったので、これがもっと使えるものならそれでも良かったんだが。こちらの細かいバージョンアップに対応してもらえるわけじゃなかったのであきらめた。

しかし、サーバ重要性は2つ目の目的こそにあったと思う。今までやりたくでもできなかった人と対戦できるようになったのだから。今でも観戦できないのは問題なんだけど。プログラム的にはさほど難しいことをしているわけではない。サーバ経由で対戦している人をデータで管理しておいて、その間のデータのやり取りをしているに過ぎない。技術的にはたいしたことではない。デュエルオンラインの方は、両方ともクライアントモードで(通常のポートとは違うポートで)サーバに接続しているだけでプログラム的にはほとんど変更なしだし。

もっとも、この「両方クライアントモード」というのが観戦機能の実装を困難にしているのだが。ちょっと解説しておくと、観戦はサーバモードデュエルオンラインに第3者が接続したときに起動し、サーバモードデュエルオンラインからデータを送ることで実現している。したがって、両方クライアントモードではデータを送る人がいなくて、また別の観戦モードなるものをつくらないといけないのである。それが結構面倒というわけだ。もちろんいずれは実装したいと思っているのだが。

手前味噌だが、サーバの登場はデュエルオンラインの環境を一変させたと思っている。サーバの無かった時代を思い出すのも難しいくらい。それだけに、私自身がサーバを運営できる環境にないのが残念である。

lostsnowlostsnow 2005/08/06 22:32 23456う:あdfgh・m、。・

2004-08-12 夏休み!

夏休みに入ったけど

一応、今日から夏休みなんだけど、やっぱりまとまった時間はなかなかとれない。さて、バージョンアップは可能なのだろうか。期待しないで待っていて欲しい。

通信部分の抱える問題

前回の続きで通信部分の抱える問題を解説しておきたい。「(サーバを利用しないと)接続するのに手間がかかる」「プライベートIP同士では(サーバを利用しないと)対戦できない」「サーバを利用してもプライベートIP同士の対戦は観戦できない」という話は前々からあるのだが、ネットワークの構造上どうにもならない話もあったりするので、ちょっと今はおいておく。3つ目は私の設計の問題なんだが…

デュエルオンラインの開発当初、通信に関してまず問題になったのは「不一致の発生」であった。当時、私個人はブロードバンドではなかったし、世間一般としてもブロードバンドが使えるのは都会だけという時代であった。なので、私は通信は極力軽くしたくて、送受信するデータは必要最小限となるように設計しようとしていた。なので、「何か操作したときに、その操作した内容を相手に送る」というのが基本的な仕様であった。例えば、フィールドにカードを置いたときには、そのカード名と置いた場所のみ相手に送るという感じ。この方式だと通信量は少なくて済むが、一度不一致が発生すると修正が不可能という問題を抱えていた。

設計当初は「ネットワークの通信状態は不一致が発生するほど悪くはならないだろう。そういう状態なら既にデュエルできる状態じゃないだろう」と思っていた。ところが、実際には不一致は結構な頻度で発生した。ちょっと驚いた。

他の問題としては「データが途中で切れる」というのもあった。プログラムとしては1電文としてまとめて送ったつもりの物が、相手には途中までしか届いてなく、それを正常と思って処理するものだから、わけのわからないことが発生した。TCP/IPパケット通信なので、原理的にそういうことは有りえるとは思っていたが、これも頻発するとは思ってなかったことである。

リリースしてから1ヶ月もたたないうちにこの2つは問題として浮上した。「TCP/IPは便利だけど、さほど信頼できるものではないんだ」というのが私が得た教訓である。今までつくったプログラムは実験室で動かすようなものばかりだったからなあ。

しょうがないので、独自のプロトコルを入れることにした。不一致対策のために「ACK」を導入した。これは、データを相手に送った後、相手からの応答があるまで次の操作はできないようにするというもの。もちろんデータを受け取った相手は、その応答を逐一送信する。通信の回数は単純に倍になるし、面倒だし、プレイヤーからすれば操作はしばらくロックされたりするし、悪いことが多いんだけど、他の解決策を思いつかなかった。何か操作をするたびに、ボタンやメニューが反転して一時的に操作できない状態になるのはこの機能のせいである。データを逐一、お互いに確認を取りながら処理することで不一致を無くそうという発想である。ちなみに応答としては、本当に「ACK」という文字列を返しているだけだったりする。本当は受信したデータをオウム返しで返すとかするといいんだけど、そこで不一致があったところでどうしようもなさそうなのでやめた(単に面倒という話もある)。

2つ目の対策として「</END>」の導入というのがある。これはデータの最後を意味する文字列であり、これが来るまで待ってから、処理を始める。したがって、データが途中で切れていても、その時点では処理は始めず「</END>」が来てから処理を始めることになる。これで、確実のデータの処理を始めることができる。ずっと「</END>」が来なかったら?というのは気にしないことにした(をぃ)。

とりあえず、この2つの対策を入れたことで、通信の安定度は格段に上昇した。しかし、問題がなくなったわけではない。

現状、やりたくてもできてない対策として「再接続」がある。ネットワークの不調により接続が切れたとき再接続して、デュエルを途中からでも再開できるようにしたいと思っているのだが、これがうまくいかない。切断されたことがうまく検知できないのである。異常な切れ方をするせいか、うまくキャッチできない。私の知識の問題なのか、Delphiコンポーネントの問題なのか、そもそもそういうものなのかはよくわからないが。そして、再接続ができたとしてもお互いの状態に不一致が発生している可能性は否定できない。異常な切れ方をしているのだから、ACKもどうなったのかわからないし、互いの状態が一致している保証はない。強制的に一致させることも考えたのだが、今の仕様では、例えば相手のデッキの中の情報は持ってないので、一方の持っている状態に強制的に一致させることはできない。互いの情報を合わせて一致させるとしても不一致をどうしょりすれば正しいのかよくわからないし。

これは一言で言うなら私の設計ミスである。最初から、通信は「操作の内容」ではなく「そのときの全情報」を送るように設計すれば良かったのだ(フィールドとか手札とか墓地とかデッキとかとにかくすべての情報を)。そうしておけば不一致が発生してもすぐにどちらかに一致させることができ、再接続も実現は簡単だっただろう(ACKは結局は必要だったんじゃないかと思うけど)。事実、観戦機能は「全情報を送る」というやり方で実装している(観戦に必要ないのは省いているけど)。デュエルリプレイ機能もその応用だったりする(観戦者に送るデータをほぼそのままファイルに落としているだけ)。「絶対にそっちの方が楽だった!」とかなり後悔している部分である。ブロードバンドがもっと普及していれば、絶対にそうしたのだが… 先見の明がなかったかなあ。

lostsnowlostsnow 2005/08/06 22:31 t7幾9@8絵rtyふじこlp;@dhjkl;yふjく8いこぅいkfvgbhn