Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2005-04-30

[栽培日誌]トマトとキュウリの植え付け

画像の説明 画像の説明

  • キュウリの苗(鎌倉野菜)× 2
  • トマト苗(鎌倉野菜)× 2
  • ミニトマト(キャロル?)× 1

キュウリのリクエストがあったので、今年は時期をずらして多めに植えようと今日から植え付け。フジスーパーの鎌倉さん野菜ブランドを購入。品種が書いていないのが痛いが、ポットの土が腐葉土でなので選択した。値段も高く198円。

トマトも少し早いが一緒に買って植え付け。 ミニトマトは東にひとつ。

去年の秋に植えたミョウガが芽を出した。 画像の説明

2005-04-30

[プログラミング]達人プログラマーその他購入

やっと買えた。とてもうれしい。

Code Complete第2版〈上〉—完全なプログラミングを目指して(スティーブ マコネル) Code Complete第2版〈下〉—完全なプログラミングを目指して(スティーブ マコネル) 達人プログラマー—システム開発の職人から名匠への道(アンドリュー ハント/デビッド トーマス) リファクタリング—プログラムの体質改善テクニック(マーチン ファウラー)

2005-04-29

[アイデンティティ]作ることと頭のよさ

頭のいい人はたくさんいることがわかったが、頭がいいことといいものを作れることは同じではないのかもしれない。もちろんものを作るにあたって頭がいいほうが有利なのは言うまでもないと思う。

2005-04-27

[プログラミング]いいコード……

それから、自分がいっている『いいコード』というのは、インデントがどうと か、そういう意味じゃないんです。十分にリファクタリングされていて、プロ グラマの意図がコードに十分に表現されていて、ほとんどコメントがいらない ようなコードです。

これはオレが目標にしていた「いいコード」のイメージそのもの。生産性とかそんな話じゃない、と言うのを聞いて少し違うものを想像してしまったようだ。

前にも書いたことがありますが、プログラムにとって一番の価値基準は、いい コードで書かれたかどうかでなく、人にどれだけ喜ばれるかということです。 ただ、これは自分が受注といった仕事をしているせいか、価値が比較的軽くな ります。芸術作品ほどの感動は求められていないといったところです。

芸術作品ほどの感動というのは大げさな気がしたが、このあたりの自分の考えはあいまいだ。もしかしたらプログラミングとプログラミングに関係ない事を混同しているのかもしれない。

自分が過去に作ったプログラムは CD に焼いてあとは売るだけという使い捨てのものが多かった。マスターを上げればそのコードは 2 度と見ずに済むことも多いので、「いいコード」に対する意識はたいへん低かった。まぁ見ずに済むと言ってしまうところが、 2 度と見たくないコードを書いていということでもあるな。

で、この『いいスタイル』と『いいプログラム』というのがやっぱり今の自分の活動に必要なものだと思う。

あれ、てことはオレが目指すべきは XP なのか。

2005-04-26

[アイデンティティ]いいコード

いいコードを書くことと高い生産性とは別の話でしょう。いや、いいコードを書けば生産性が高くはなるんでしょうけどね。

でも、自分は生産性云々でいいコードを書きたいと思ってるわけじゃないんです。悪いコードに我慢ならないからいいコードを書きたいんです。悪いコード を見ると無性に書き直したくなるんです。それはもう生産性とかそんな話じゃ ないんです。

悪いコードに我慢ならないからいいコードを書きたい、というのはあまり感じない。いいアプリを書きたい衝動の方がはるかに大きく、いつも自分やユーザーがそのアプリを使う姿ばかり頭に浮かんでくる。無意識にエンドユーザの反応をずっと想像している。

たまに他人のソースを見て、ほんとに几帳面だなあと感じることがよくある。 オレはああいうのは書けない。

全部が全部を生産性に結びつけるのはプログラミングを味気ないものにしちゃ うんじゃないでしょうか。

全部が全部かはわからないけど、 オレにとってのプログラミングはコードを作ることではなくて、ソフトを作ることだから生産性はとても重要だ。

いいコードが書きたいという衝動はそれほどでもないということか。

2005-04-24

[栽培日誌]追肥

去年の夏から東に寝かせておいた堆肥(枯れ草と牛糞を積んでおいたもの)を東から 3 列に入れた。時期が少し遅くなった。ここでナス科を育てる予定。この 3 列の一番西側のあたりは一昨年ピーマンを植えた気がするが、まあやってみよう。

--

画像の説明 画像の説明 今日はトウモロコシと枝豆の種を蒔いた。

2005-04-24

[開発ログ]ログイン画面完成

ユーザー作成とユーザーログインの WEB ページができた。

これが Jewel-mmo サービスの最小構成か。

--

テンプレートはこうした。テンプレート内に含めるロジックをファイルの先頭に移動。これならこのままでもやっていけそうだ。

<%
  name = @cgi.params['name'].first
  pass = @cgi.params['pass'].first
  sid = nil
  error = nil
  if name
    begin
      require 'command/login.rb'
      raise Core_Error unless (com = Login.new(nil, name, pass)).result
      sid = com.result
      @cgi_header["cookie"] = CGI::Cookie::new({"name" => "sid", "value" => [sid]})
    rescue Core_Error
      error = $!.inspect
    end
  end
%>

<html lang="ja">
<head>
<meta http-equiv="Content-type" content="text/html; charset=EUC-JP">
<meta http-equiv="Content-script-type" content="text/javascript">
<title>ログイン</title>
</head>
<body>

<h1>ログイン</h1>

<% if sid %>
  <head><meta http-equiv="refresh" content="5;url=<%= jmp_url('usermain') %>"></head>
  <p>Wait or <a href="<%= jmp_url('usermain') %>">Click here!</a></p>
<% else %>
  <% if error %>
    <p>Error : <%= h(error) %></p>
  <% end %>
  <form action="<%= jmp_url %>" method="post" class="login_form">
     <input type="hidden" name="tmpl" value="<%= h(@tmpl) %>" />
     user name : <input type="text" size="10" name="name" value="<%= h(name) %>"/>
     password : <input type="pass" size="10" name="pass" value="<%= h(pass) %>"/>
     <input type="submit" value="login" />
  </form>
  <p><a href="<%= jmp_url('useradd') %>">ユーザー登録画面</a></p>
<% end %>

</body>
</html>

現状のランチャーは以下。

#!/usr/bin/env ruby
require 'cgi'
require 'erb'
include ERB::Util

def jmp_url(tmpl=nil, params=nil)
  url = $0
  url += "?tmpl=#{tmpl}" if tmpl
  h(url)
end

@cgi_header = {}
@cgi = CGI.new("html3")
begin
  $:.unshift '../core/'
  require 'jewelcore.rb'
  include JewelCore

  @sid = @cgi.cookies['sid'].empty? ? nil : @cgi.cookies['sid'].value.first
  @tmpl = @cgi.params['tmpl'].first
  raise @tmpl if @tmpl =~ /[^\w_-]/

  html = ERB.new(File.read("./#{@tmpl}.htm")).result(binding)
rescue Exception
  html = "<H2>Error</H2>\n#{h($!.inspect)}"
  html += '<PRE>' + $@.map{|s| h(s) }.join("\n") + '</PRE>'
end

@cgi.out(@cgi_header) { html }
2005-04-23

Rails 合宿 (4/30?)

実家の群馬でやることになった Rails 合宿。人は集まるだろうか。微妙だ。

2005-04-23

[開発ログ]WEB インターフェース作成中

こんな感じの erb スクリプト。 ロジックは core コマンドになっているのでそれを使うコードになる。

<html lang="ja">
<head>
<meta http-equiv="Content-type" content="text/html; charset=EUC-JP">
<meta http-equiv="Content-script-type" content="text/javascript">
<title>ログイン</title>
</head>
<body>

<%
  name = @cgi.params['name'].first
  pass = @cgi.params['pass'].first
  sid = nil
  error = nil
  if name
    begin
      require 'command/login.rb'
      raise Core_Error unless (com = Login.new(nil, name, pass)).result
      sid = com.result
    rescue Core_Error
      error = $!.inspect
    end
  end
%>

<h1>ログイン</h1>

<% if sid %>
  <p><%= h(name) %> : ログインしました。</p>
  <p>sid : <%= h(sid) %></p>
<% else %>
  <% if error %>
    <p>Error : <%= h(error) %></p>
  <% end %>
  <form action="<%= h(@action_script) %>" method="post" class="login_form">
     <input type="hidden" name="tmpl" value="<%= h(@tmpl) %>" />
     user name : <input type="text" size="10" name="name" value="<%= h(name) %>"/>
     password : <input type="pass" size="10" name="pass" value="<%= h(pass) %>"/>
     <input type="submit" value="login" />
  </form>
<% end %>
<p><a href="<%= h(@action_script) %>?tmpl=useradd">ユーザー登録画面</a></p>

</body>
</html>

前はテンプレートとプログラムを別ファイルに分けていたのだが、面倒なのでひとつにまとめた。これくらいならデザイナも理解してくれる。規模によっては切り分けが必要か。

でも、これをデザイナに渡すと複雑な HTML になって返ってくるわけで、その中の Ruby スクリプトを編集するのも面倒な気もする。難しいところか。

2005-04-23

[プログラミング]いいコードが書きたい

少し前に書いたコードが結構ダメなのがわかる。当然今書いているコードもダメなコードだろう。それが自覚できるようになったことは大きな進歩だと思う。

いいコードを書けるようになりたいが、これはそう簡単に身につくものではなさそうだ。もしいいコードを書くことで今よりも生産性が大きく上がるのなら、上達したい。おそらくはいいコードをひたすら読むのがいい気がするが、いまいちやる気になれない。どうしたものか。

2005-04-22

[開発ログ]回復コマンドを書いてみたが

手探りで使っている Acrive Record の使い方やその他どうもすっきりしない。

class Heal < CoreCommand
  def exec
    doll_id = @options[0]
    doll = @session.user.dolls.find(doll_id)
    return nil unless doll.temp_states.find_all("expiration_time > now()").empty?

    doll.temp_states.find_all("state = 'action_wait'").each{|s|s.destroy}
    wait = 10
    doll.temp_states.create(:state => "action_wait", :expiration_time => Time.now + wait)

    d = 1
    old_hp = doll.hp
    doll.hp = old_hp + d
    doll.hp = doll.state.hpmax if doll.hp > doll.state.hpmax
    doll.save
    doll.hp - old_hp
  end
end

そもそもローカルの時間と DB の時間のズレが問題になりそうだし。後半のロジックももっと短く書けないものだろうか。 ツッコミお願いします。

2005-04-22

[アイデンティティ]インプットとアウトプットのバランス

<URL:http://rucila.s43.xrea.com/memo/?date=20050421#p06>

オレの場合は圧倒的にインが少なすぎる。非常にバランスが悪い。 というのに気づいてここ一年は意識して勉強しているのだが、それでもまだまだインが少ないと思う。

問題は書くのは楽しいけど読むのは面倒と感じてしまう根本の性格か。 と言うわけで読書会に参加したり、面白い本がないかを聞いたりしているわけだ。

2005-04-21

[アイデア]究極の PL 対策

PL 対策で悩んでいた。 前からいろいろ考えていたのだが、最後にあることに気がついた。 レベルをなくせばいい。 RPG に経験値やレベルは必須ではない。 とくに寿命があるこのゲームならレベルなんてなくてもキャラ育成のロジックが組める。というか寿命があるのに経験値を稼がなくちゃいけないとしたら、それはもうただの毎日のノルマでしかない。 ついにプレイヤーはあの煩わしいレベル上げの作業から解放されるのだ。

むらさま方式でキャラを育てることができればそれで十分だろう。

2005-04-21

[プログラミング]過去のコードと未来のコード

うひゃあ、 2 年前に書いたコード見たらひどいことになってる。これほんとに ruby か。 いまのコードを 2 年後に見たらさぞかしひどいことだろう。

はやくコードコンプリート読まないと。

2005-04-21

[アイデア]エリアマスターと守衛

エリアマスターが不在のエリアで、人形にエリアマスターのカードを使うとユーザーはそのエリアのエリアマスターとなることができる。

カードの対象となった人形は戦闘能力値が約 10倍 にパワーアップし、そのエリアの守衛として最強のキャラクターになる。エリアマスターであれば他の人形に守衛のカードを使って守衛の数を増やすことが可能。

エリアマスターのカードや、守衛のカードによって守衛と化した人形は強力な戦闘能力と引き替えに、いくつかの制限が課せられる。

  • 守衛は成長しない
  • 守衛はトレードその他のいくつかのアクションを実行出来ない
  • エリアマスターとなったユーザー(とその人形達)はそのエリアをでることができない。

町には通常治安を維持するためにエリアマスターと守衛が存在する。 たいてい守衛は 24 時間 bot によってコントロールされ無条件に Evil のキャラクタを攻撃するか、 Evil キャラクタのアクションを厳しく監視する。

そう言えば人形の性格による攻撃ルールをデジタル化していない。メモ噴出する前にアップしておかねば。

2005-04-21

[アイデア]人形の使い方

イメージが固まってきた。これまでのアイデアの断片を関連付けてゆく。

人形の運用には次のようなパタンがある。

  • 戦闘型で軍事力重視
  • 農夫型で農業重視
  • 子育て方で育成重視
  • メイド型でイメージ重視
  • 守衛にして治安を確保し町を作る

プレイヤーがすべきことも決まってきた。これらの要素を最小限の小さなシステムでルール化しることが大切だ。

2005-04-20

[アイデア]何はなくともステータス画面

たとえ内容が機能してなくても、自分好みのステータス画面が作れるだけでいいのではないだろうか。

となるとやっぱり WEB だな。

2005-04-20

[アイデア]チャットサーバーのイメージ

チャットサーバーについて。 今日も思いついたことを深く考えずにただそのまま書いてみる。

チャットサーバーでできること。

  • NPC との会話 …… Core コマンド
  • プレイヤー同士の会話 …… 通常の irc によるチャット
  • プレイヤー bot との会話 …… ピリカ → irc → ピリカ
  • 自分の bot との会話 …… クライアント〜ピリカ間の通信
  • エリア URL の問い合わせ …… クライアント → アイリ → クライアント
  • ショップ URL の問い合わせ …… 同上
  • エフェクト情報の取得 …… Core コマンド処理 → アイリ → ピリカ → クライアント

プレイヤー bot とのトレード

  1. トレード条件の問い合わせ …… ask name
  2. 条件表示 …… 「trade0: 相手 : やくそう あなた : 10J 」
  3. 「交換しますか?はい/いいえ」 …… 「はい」 → trade name 0
2005-04-20

[開発ログ]ircd

ircd-hybrid がいいかなと思い、

emerge -p ircd-hybrid

したら、

Calculating dependencies
!!! All ebuilds that could satisfy "ircd-hybrid" have been masked.
!!! One of the following masked packages is required to complete your request:
- net-irc/ircd-hybrid-7.0.3 (masked by: ~x86 keyword)

うーむ。

2005-04-19

[開発ログ]アイリ

Nadoka をサーバーにもクライアントにも使うので、サーバー上の irc チャンネル内のユーザー管理を行う Nadoka をアイリと名付けだ。ちなみにクライアントの方はピリカ。

アイリのコードは Nadoka の設定ファイルと bot になる。

サーバー側の bot を使う処理は NPC の制御や、お店などいろいろある気がしていたのだが、よく考えるとそれらは一ユーザーと同じ条件下で動かす bot でもよい。ただそれだとパフォーマンスが問題になるかもしれないが。

アイリの本分はエリア毎に存在するチャンネルの管理だ。 オペーレータがどのような操作が可能なのかよく知らないので、まず irc を調べないといけない。

--

http://irc.nahi.to/command.html

なるほど。

join 制限は +sn に加えて、

/mode ch +i

しておけばよさそうだ。もし、アイリがオペ権限を失った場合は、そのチャンネルは破棄して新しいチャンネルを作ればよい。

エリア移動の時

クライアントがエリア移動コマンド実行 → 移動認証(成功ならアイリは invite を実行) → クライアントはエリアのチャンネル名を受け取る → ピリカによる自動 part と join

アイリ起動時

エリア数の分のチャンネル開設 (join) 。

ピリカ起動時

キャラが wlogin しているなら、エリアログインだろうか。

2005-04-19

[アイデア]ゲームの目的と富

ゲームの目的を考えるととりあえず 2 つ思いつく。

ひとつは自分のプレイスタイルを作ること。それは 8 体のキャラクタに好きな名前を付けるところから始まって、好きな絵を描いて、 bot を駆使して好きに振る舞わせるということ。あとは自分にだけ見える世界観そのものをカスタマイズすることも可能。

もう一つはゲームの中で優位な地位を築くこと。富を作ることだ。 で、このゲームワールドでの富とはなんなのか。 やりたくないのは、モンスターを倒すとお金が手に入り、それを集めることが富になるというもの。モンスターがアイテムを落としても同じ事。 じゃあ、どうやって富を生み出すのかというと、基本は土地に種をまけば自然と食料が育つので、それを栽培して収穫することが富になる。自分が食べる分はそれでたやすくまかなえるが、強力なアイテムを作るにはいろいろな地方で生産されたたくさんの物質を合成しなければならない。お金は最初から一定の量がワールドに存在している。お店もユーザ主体のぶつぶつ交換なので物価は自然に決まる。決して生産出来ない宝石をお金のかわりにしてもいいかもしれない。

これが基本。実際はいちいちめんどくさくて栽培なんてやってられない。冒険にも出かけないといけない。でも、そうやって時間と暇さえあれば作れる食べ物にも自然と価値が生まれていく。

2005-04-18

[開発ログ]Google Maps

遅ればせながら時代は WEB だということに気づき(例によって妻に遅すぎと突っ込まれつつ)調査を始める。

http://maps.google.com/

wema を見たときにこういうことができそうだとは思った。ただ、この使いやすさと速度と安定度は実際に見ると衝撃的だ。

つまり何でもありだ。ページのリロードなしでいくらでもゲーム画面を更新できる。この技術は将来的なフロントエンドの基盤となりえる。

自分のプログラマとしての得意分野を考えると Ajax に今から注力するのもありかと思うが、やっぱり今は Ruby でのコア実装に集中すべき時期だ。ゴージャスな GUI に手を出すのは早すぎる最適化だろう。

2005-04-18

[開発ログ] 次に何を実装するか考えよう

コマンドのランチャーとテスト環境のフレームワークができたので、次の段階へ進むことができる。

次の作業として考えられるのは

  • WEB インターフェースに関する考察
  • Nodoka でアイリ&ピリカを実装

あたりか。

WEB インターフェースについては、エンドユーザから見れば

  • 基本が WEB でその他はおまけの便利(マニアック)なツール

だが、実装から見れば

  • 基本はコマンドによる各種処理で WEB はおまけ

であるから、 WEB は後回しでもよさそうだ。 ただしゲームデザインは WEB のインターフェースを考慮する必要がある。

このあたりをもっと考えてみよう。

--

考えがなかなか進まない。 WEB ページで MMORPG をプレイする姿がなかなかイメージできない。しかしそれは Ajax でなくたって可能なはず。既存のモデルに思考が縛られているだけだ。

プレイの流れを考えてみる。

  1. ユーザー登録
  2. キャラ作成
  3. ワールドへ放り出される
    • 地理の把握
    • 移動
    • 戦闘が発生する
    • お店
    • 会話
    • 装備、アイテムを使う

ワールドの時間はリアルタイムに進行しているはずなので、その動的な世界観をどう表現するか。チャットウィンドウにリアルタイムでログが流れればそれは十分に時間軸を表現できる。

2005-04-18

[開発ログ] config/environment.rb

開発とテストの DB を分けたかったので rails の config/environment.rb をまねて yaml でそれぞれの DB 設定を記述する方式を導入。

config/database.yml

development:
  adapter: mysql
  database: jewel
  host: localhost
  username: root
  password:

test:
  adapter: mysql
  database: jewel_test
  host: localhost
  username: root
  password:

production:
  adapter: mysql
  database: jewel_production
  host: localhost
  username: root
  password:

ActiveSupport を知らないのでその辺は全部削除。

2005-04-17

[アイデア]最大 HP が低いほど強い

いままで HP と呼んでいたものは仮に耐久力と呼ぶことにする。

新しい HP は 1 〜 10 の数値になる。 レベルアップ等によってこの HP パラメータは成長しない。 そしてダメージの計算は……うーむこれはコードで書いたほうが早い。

hp_max = 5
hp = hp_max
old_hp_max = 75

として、ダメージ計算は

hp -= damage / (old_hp_max / hp_max)

とする。

hp_max が低いほうが切り捨てるダメージ量が多くなるので有利。 hp_max が 1 なら従来の最大 HP 以上のダメージを一度に与えない限りダメージは 0 になるわけだ。

たとえばボス戦などではいかにダメージ 1 を与えるかが重要になる(ボスの HP が 10 しかないのだから。魔法剣のサンダガでためる× 10 とバイキルトした最強のジョブアビを 200% 連携でヒットさせてやっとダメージが 0 から 1 になるわけだ。もちろんこの連携を成功させるまでの準備時間がすごく長いので、最強レベルのアーマーナイトを先頭に配置し、魔法使い達はそいつに何重ものバリアを被せてボスの攻撃をしのぎ続けなければならないのだ……)。

昔から キャラの最大 HP は 10 くらいでいいんじゃないかと思っていたので、これは非常にいいアイデアだ。

2005-04-17

[日記] RHG 読書会行ってきました

正面に座っていたのが arton さん、その左に順に青木さん、ささださん、高橋さんと豪華な顔ぶれで、自分がその場に面と向かって座っているのが不思議な感じがした。隣は nobsun さんだった。

最初の話は言っている意味はわかるけど知らないことばかりなのでわからないという不思議な感じ。わかりやすくて細かい話も記憶に残っている。今後勉強していくと今回の話が役に立つだろうと思う。 WEB の話はちょうど WEB に関心が出てきたところでもあったので非常に参考になった。

arton さん、ありがとうございました。

2005-04-16

[プログラミング]WEB アプリ

ハッカーと画家を読んでいて、 WEB アプリについての見方が変わった。そうか時代は WEB だったんだ。

WEB アプリだとオレは掲示板を CGI で書くくらいしかできない。それなりのセキュリティホールというおまけつきで。それくらいの技術と知識しか持ち合わせていない。 WEB というものをもう少し真剣に考えたほうがよさそうだ。

2005-04-16

[日記]はっとりからメールがきた

2, 3 年会っていない友人から突然メールが来た。偶然このサイトを訪れて、オレに気づいたらしい。

世間は狭いようだ。

とりあえず Mixi に誘ったがそれっきり連絡がない。

それにしても最近カウンタがやたらとぐるぐる回る。

2005-04-15

[アイデア]Jewel-mmo と WEB アプリ

敷居を低くすることは重要だと考えていたが、完全な WEB アプリにするところまでは考えが至っていなかった。

つまりクライアントに何かしらをインストールさせることを前提としていたわけだが、 WEB だけでも動く形を用意することについても考えてみたほうがいいだろう。

表面上は「 WEB アプリとしての最小構成」と「その他便利ツール」という位置づけにしてしまうとか。

2005-04-14

[開発ログ]テストに挑戦

よく知らないが見よう見まねでテストを書いてみる。

require 'jewelcore.rb'
require 'arconf.rb'

module JewelCore
  class Useradd < CoreCommand
    class Core_name_exists < Core_Error ; end
    class Core_name_is_too_short < Core_Error ; end
    class Core_password_is_too_short < Core_Error ; end
    class Core_invalid_user_name < Core_Error ; end
    def find_session sid
    end

    def exec
      name = @options[0]
      pass = @options[1]
      raise Core_invalid_user_name, name if name =~ /[^0-9A-Za-z_-]/
      raise Core_name_exists, name if User.find_by_name(name)
      raise Core_name_is_too_short, name.size.to_s if name.size < 3
      raise Core_password_is_too_short, pass.size.to_s if pass.size < 3
      user = User.create(:name => name, :password => pass)
      true
    end
  end
end

if defined? Test::Unit
  class Test_CoreCommands < Test::Unit::TestCase
    def test_useradd
      [
        {:name => 'username', :password => 'pass'},
        {:name => '000', :password => 'pass'},
        {:name => '-00', :password => 'pass'},
        {:name => 'aa_', :password => 'pass'},
        {:name => '0123456789abc', :password => 'pass'},
      ].each do |v|
        user = OpenStruct.new v
        assert Useradd.new(nil, user.name, user.password).result
        assert_raises Useradd::Core_name_exists do Useradd.new(nil, user.name, user.password) end
      end
    end

    def test_useradd_faile
      ['aa/','aa*','00"','00あ'].each do|name|
        assert_raises Useradd::Core_invalid_user_name do Useradd.new(nil, name, 'pass') end
      end

      ['','u','uu','0'].each do|name|
        assert_raises Useradd::Core_name_is_too_short do Useradd.new(nil, name, 'pass') end
      end

      ['','u','uu','0'].each do|pass|
        assert_raises Useradd::Core_password_is_too_short do Useradd.new(nil, 'user', pass) end
      end
    end
  end
end

コードそのものとテストコードを離したくなかったので同じファイルに書いている。テストを書くのはそれほど面倒ではない。逆に端末でいちいちコマンドを実行しながらデバッグするより楽かもしれない。これくらいだと自然にテストファーストができる。

例外クラスを作るのは初めてかもしれない。こんな使い方でいいのだろうか。

パスワードはノーチェックで DB 行きで大丈夫だろうか。

上記テストコードを呼び出すスクリプトはこんな感じ。

#!/usr/bin/env ruby
require 'test/unit'
Dir.glob('command/*.rb').each{|s| require s}

class Test_CoreCommands < Test::Unit::TestCase
  include JewelCore
  def setup_user(user)
    User.destroy_all
    Useradd.new(nil, user.name, user.password)
    user.sid = Login.new(nil, user.name, user.password).result
    user.db = CoreCommand.new(user.sid).session.user
    user
  end

  def setup
    require 'ostruct'
    @user = setup_user OpenStruct.new(:name => 'testman00', :password => 'pass')
    @target = OpenStruct.new :name => 'target00', :password => 'pass'
    #setup_user @target
  end

  def teardown
  end

  def create_doll(user, num)
    Filldolls.new(user.sid, num)
  end

  def test_
  end
end

テストは重要な気がするのでちゃんと勉強したい。

2005-04-14

[プログラミング] YARV で HSP となでしこ

そうそう、

<URL:http://www.namikilab.tuat.ac.jp/%7Esasada/diary/200504.html#d1>

これは 4/1 ネタじゃないとのこと。 オレは前から話を聞いていたからもともとネタとは思っていなかったのだけど。

とても楽しみ。 HSP のライブラリが Ruby から使えればすごく楽しいことになるはず。

2005-04-14

サーバー落ちてました

昨日の朝、長男によるコンセント抜きでサーバーが落ちたのですが、 Apache 起動するの忘れてました。さっき起動させました。すいません。

2005-04-13

[Ruby]OpenStruct っぽい Hash

def o.method_missing(name, *args); include?(name) ? self[name] : super; end

def o.method_missing(name, *args); fetch(name){super}; end

と書ける。

2005-04-13

[むらさまプレイ日記] ょ。君の成績

ょ。君の総合成績

  • ALL 100勝82敗74分 勝率.390
  • Grade1 9勝24敗17分 勝率.180 優勝0回
  • Grade2 35勝36敗36分 勝率.327 優勝1回 ★
  • Grade3 49勝16敗20分 勝率.576 優勝6回 ★★★★★★
  • Grade4 7勝6敗1分 勝率.500 優勝1回 ★

よかった。普通はこうなるはず。

あれ、 G1 未勝利じゃないですか。頑張ってください。

オレは G1 の時しかやる気がでない模様。というか育成にしても下位にいるときから G1 での戦いを焦点にしいる。他の人の成績も知りたい。

2005-04-13

[アイデア]保険と選挙

死亡保険とか。選挙でその国の首相を決めるとか。

ユーザーが勝手にこういう仕組みを作れるとよい。契約書や誓約書システムはいいアイデアかもしれない。

2005-04-12

[むらさまプレイ日記] これまでの総合成績

総合成績

  • ALL 130勝83敗84分 勝率.437
  • Grade1 70勝22敗40分 勝率.530 優勝4回 ★★★★
  • Grade2 25勝15敗20分 勝率.416 優勝2回 ★★
  • Grade3 33勝45敗22分 勝率.330 優勝4回 ★★★★
  • Grade4 2勝1敗2分 勝率.400 優勝0回

G1 の勝率が一番高いという謎の結果に。他のみなさんどうですか? トラックバック募集。

2005-04-11

[開発ログ]とりあえず攻撃コマンド

PC がログインできるようになったので、とりあえず攻撃がしたい。実装の注意点はこんなところか。

  • 攻撃の種類には直接、魔法、アイテムがある
  • 回復アクションも攻撃と同じ処理がよい
  • 相手の HP を 0 にしたときは経験値やアイテムの取得がある
    • ただ今回は一時的な経験値システムでレベルアップ処理を別にできる

あと NPC の扱いをどうするか。どのようにワールドにログインさせるか。

--

とりあえず攻撃できるようになった。次はエフェクト情報をクライアントにばら撒くチャットサーバー(アイリ)について考えるか。

--

ActiveRecord の使い方が甘いので後々修正が必要だろう。

<URL:http://api.rubyonrails.com/?u=ar.rubyonrails.com>

昨日と今日の成果。 ActiveRecord 効果でコマンドのコードが短くなっている。

39     ./www/cmdlauncher.cgi
39     .cgi total

10     ./conf.rb
5      ./lcmdlauncher.rb
56     ./arconf.rb
18     ./jewelcore.rb
15     ./command/users.rb
11     ./command/dlist.rb
35     ./command/login.rb
12     ./command/logout.rb
19     ./command/filldolls.rb
12     ./command/wlogin.rb
40     ./command/attack.rb
12     ./command/wlogout.rb
245    .rb total

59     ./db/tables.sql
59     .sql total

8      ./db/uses.txt
8      .txt total

0      .html total

total  351 lines
 .cgi  39
 .rb   245
 .sql  59
 .txt  8
 .html 0
2005-04-11

[開発ログ]コマンドの結果は yaml

なのでこんな感じで使う。

./core.rb dlist | ruby -r yaml -e 'p YAML::load($stdin.read)'

こんな形でコマンド呼び出しはクライアントから独立している。これがもっとも簡単なクライアントの実装である。

yaml 便利。最近は他の場面でも使っている。

パイプがわかってきた。

2005-04-11

[アイデア] むらさま実装案

ロジックはコマンドに置き換える。 WEB インターフェースは ERB からコマンドを呼び出す形でよい。

2005-04-10

[開発ログ]コア開発

ActiveRecord を使っての実装を開始。

下記はセッション ID を受け取って、そのユーザーの人形リストを返すコマンド。

class Dlist < CoreCommand
        def session
                @session = Session.find_all("sid = '#{@options[0]}'")[0]
        end

        def exec
                @result = session.user.dolls
        end
end

こいつはすごい。 それに、今は MySQL だが他の DB に移行してもなんら問題ないだろう。

今後は ActiveRecord に注目だ。

2005-04-10

[アイデンティティ]仕様とコード

文章で正確な仕様を書くとことはできない。正確な仕様を書きたいならコードで書けばよい。

しかし現段階では厳密な仕様は不要でコードにする必要はない。具体化するのは最後でよく、それまでは文章とか絵とかあいまいなイメージでいいのだ。あいまいなイメージの断片の集まりは柔軟で仕様変更に強い。

逆にコードに落ちるところまで具体化してしまうととたんに変更に弱くなる。それは脳内イメージの柔軟さとは比べ物にならない。

2005-04-09

[アイデア]魔法システム

発掘されたメモにより魔法システムの方針が決まったの書いておく。

攻撃魔法について。

まずレジスト判定。 ダメージを受ける者のレジスト確率( 0% 〜 100% )で命中判定を行う。 キャラクタのレジスト確率は基本的に 0% 。このパラメータは特殊な能力である。

ダメージは魔法の種類で決まる。ただし受ける者の「運」でダメージが半分になる場合がある。

属性について。魔法攻撃には 4 種類の属性がある。

ダメージ = 魔法基本ダメージ * 攻撃属性n値 / 防御属性n値

「属性 0」 は回復魔法に用いる。アンデッドキャラは「防御属性 0」 が -1.0 となる。

2005-04-08

[開発ログ]メモ発見

会社の机に埋もれていた。やったー♪

まほ〜まほ〜

2005-04-07

[アイデア]コマンドアイデアメモ

一枚だけ見つかったので電子化しておく。

  • dlist
  • dselest ドールセレクト
  • wlodin …… state 作成⇒エリアへ
  • ride? 0 …… のりうつるコマンド
  • item スペルカードも?

その他

  • スペルユーザーは攻撃回数を1回増やせる
  • アクションに手持ちのスペルカード詠唱あり。レベルによってランクとウェイト時間が変わる
  • S ランクは 200 時間とか⇒使い捨てキャラ対策
2005-04-07

[開発ログ]メモ紛失?

1,2 ヶ月前に書いたゲームデザインのメモどこやったかな。プリントアウトしたるびま記事の裏に書いたのが数枚あったはずなんだけど。

かなり集中して書いたものだったので、あれ捨ててたら悲しいなあ。

2005-04-03

[家族]お花見

まだ早いが、天気がいいので大池公園に行って来た。

画像の説明 画像の説明 画像の説明

2005-04-03

[アイデンティティ]夢のよう?

この土日はこれといった予定もなく家族とのんびり過ごした。

暇なので面白いゲームでもやりたいなと思うものの、面白いゲーム知らないし、ムラサマも足掛け2年以上遊んでてさすがに飽き気味だし(でもいまだに毎日やってたりする)はやく自分で新しいゲーム作らないといけないなと思う。

というわけでデータベースの設計に着手しようとしているわけだが、ふとこんなことを思い出した。小学生のころからRPGのシステムとかパラメータとかをノートに何度も書いていた。プログラミングのスキルはなかったのでルールを書いては、弟を集めてサイコロでゲームを進行させていた。当時からすれば今はプログラミングのスキルが身につき、というか既に何本ものゲームソフトを世に送り出し、自分が主軸となって開発したソフトを数十万の人が買ってくれたりもしているわけで、まるで夢のような状態にあるわけだ。 Ruby もあるし、今なら少しがんばれば自分の作りたいゲームが自分の手で作れる。

がんばろう。

2005-04-02

[栽培日誌]雑草狩り

冬の間放置しっぱなしだった雑草を鎌で刈る。

去年の秋から積み上げておいた雑草はいまだ形が残っていて分解されてない様子。これを畑に入れていいのだろうか。

2005-04-02

[日記]フットサルやってきました

画像の説明

いやあ、本当に楽しかったです。

最初のころより絶対うまくなってるよオレ。うんうん。

ゲームが面白い→うまくなりたいので練習する→うまくなるとよりゲームが楽しい→もっと練習したくなってくる

という楽しいスパイラルが発生してます。運動不足は解消され、体脂肪も減っていることでしょう。これで体重を増やせれば筋肉モリモリですよ。

サッカーなんて体育でやったくらいで、もう観戦するだけのものと思ってました。自分でプレーすると観戦もより楽しくなります。

--

mixi より抜粋。最近 mixi にパワーが移行してる。仕事の関係で度開発が進んでいないのもあるのだが。

2005-04-01

ルビま!

ルビま!も今回で最終回。

キャラクタを書いてくれた AYU2 さん、デザイン全般をやってくれたゆのじさん、ありがとうございました。