Slide 1

Slide 1 text

yumu 分散オブジェクトで遊ぼう! dRubyで作るマルチプレイヤー迷路ゲーム

Slide 2

Slide 2 text

今日話すこと ● ゲームの概要 ● dRubyについて ● ゲームのアーキテクチャ ● バグ集 ● 改善したい点

Slide 3

Slide 3 text

自己紹介 yumu(湯村 美吹香) ● 新卒3年目 Webエンジニア ● 最近はTerraform > k8s manifest > Ruby ● 好きな漫画:メイドインアビス ● X:@myumura3

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

ゲームの概要

Slide 8

Slide 8 text

ゲームの概要 ● https://github.com/myumura/druby-game ● 通信にdRuby、WebSocketを使用 ● 3D迷路環境 ● マルチプレイヤー対戦 ● プレイヤーのロールによって異なる目標 ● 5分間のタイムリミット 簡略化した地図

Slide 9

Slide 9 text

ゲームの概要 Hunter ● Survivorを全員捕まえて 脱出を阻止する Survivor ● 3つの鍵を集める ● 脱出地点を見つけて ● 脱出する VS

Slide 10

Slide 10 text

Demo 音量注意! PCの場合は矢印キーで移動

Slide 11

Slide 11 text

dRubyについて

Slide 12

Slide 12 text

dRubyの基本概念 ● 分散オブジェクトプログラミング のためのRuby標準ライブラリ ● 異なるRubyプロセス間でオブジェクトを共有 し、メソッド呼び出しを可能にする プロセスA game.move(‘up’)
 プロキシ オブジェクト プロセスB def move(direction)
 # 処理
 end
 dRuby

Slide 13

Slide 13 text

dRubyで”Hello, World!” require 'drb'
 
 class HelloWorld
 def say_hello(name)
 "Hello, #{name}!"
 end
 end
 
 # オブジェクトを公開
 DRb.start_service('druby://localhost:8787', HelloWorld.new)
 DRb.thread.join
 サーバー側 require 'drb'
 
 # リモートオブジェクトへの接続
 DRb.start_service
 hello = DRbObject.new_with_uri('druby://localhost: 8787')
 
 puts hello.say_hello("関西Ruby会議") # => "Hello, 関西Ruby会議!"
 クライアント側

Slide 14

Slide 14 text

Why dRuby? ● シンプルな実装で分散処理を実現できる Rubyのメソッド呼び出しと同じ書き方でネットワーク越しの連携が可能 https://www.amazon.co.jp/dRubyワークショップのためのガイド-関将俊-ebook/dp/B0F4XT5L78

Slide 15

Slide 15 text

ゲームのアーキテクチャ

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

ruby.wasm…?

Slide 18

Slide 18 text

ruby.wasm…?

Slide 19

Slide 19 text

ゲーム全体のアーキテクチャ ● 3D迷路の描画 (Three.js) ● ユーザー入力の処理 ブラウザ JavaScript ● WebSocketサーバー (faye-websocket) ● dRubyクライアント 中間サーバー Sinatra ● ● dRubyサーバー ● ゲームロジックの ● 集中管理 ゲームサーバー Ruby WebSocket dRuby

Slide 20

Slide 20 text

GameServerクラスの役割 ● ゲーム状態の一元管理 プレイヤー・迷路・鍵・脱出ポイントなど ● プレイヤーの参加・離脱処理 ● プレイヤーの移動・衝突判定 ● ゲームタイマーの管理 class GameServer
 def initialize
 @game_logic = GameLogic.new
 @timer_thread = start_timer
 end
 
 def move_player(name, position, rotation)
 # 移動処理
 end
 
 def collect_key(name, key_id)
 # 鍵の収集
 end
 # 省略
 end


Slide 21

Slide 21 text

GameLogicクラスの役割 register_player move_player get_game_state collect_key escape def move_player(name, position, rotation)
 player = @players[name]
 return false unless player
 return false unless player.can_move?
 
 # 障害物との衝突チェック
 return false if collision_with_obstacles?(position)
 
 player.position = position
 player.rotation = rotation
 # 鍵・脱出・捕獲チェック
 check_game_state
 true
 end


Slide 22

Slide 22 text

リアルタイムな操作の実現 1. キー入力 2. WebSocketで送信 3. ゲームサーバーで処 理 4. 全クライアントに配信 5. 画面更新

Slide 23

Slide 23 text

マルチスレッド ● dRubyメインスレッド ● WebSocket状態更新スレッド ● タイマースレッド

Slide 24

Slide 24 text

Why Websocket? ● dRubyだけだとブラウザと直接話せない ? ruby.wasm?

Slide 25

Slide 25 text

https://speakerdeck.com/lnit/kansairubykaigi08-wasm-websocket

Slide 26

Slide 26 text

バグ集

Slide 27

Slide 27 text

相手のアバターが見えない

Slide 28

Slide 28 text

画面がブルブルする

Slide 29

Slide 29 text

捕まったサバイバーが移動できる

Slide 30

Slide 30 text

他にも... ● 壁に突き刺さる ● 壁に挟まれて動けない ● 鍵が鍵っぽい形にならない ● タイマーが開始しない ● 音が癇に障る ○ Web Audio API(ブラウザ標準API)

Slide 31

Slide 31 text

改善したい点

Slide 32

Slide 32 text

改善したい点 ● dRuby ○ セキュアではない ○ パフォーマンスの懸念 ● ruby.wasmで動かしてみたい ● (細かいバグはいっぱいある😂)

Slide 33

Slide 33 text

まとめ

Slide 34

Slide 34 text

dRubyで作るということ ● プロトコルを意識せず、Rubyのメソッド呼び出しとして書ける ● 簡単に使える!!! プロセスA game.move(‘up’)
 プロキシ オブジェクト プロセスB def move(direction)
 # 処理
 end
 dRuby

Slide 35

Slide 35 text

Vibe Coding

Slide 36

Slide 36 text

最初はここから ...

Slide 37

Slide 37 text

昨日(今日?)の深夜やったこと ● VPSで公開! ● 効果音の修正! ● モバイルブラウザ対応!

Slide 38

Slide 38 text

Kaigi Effect最高!🥳

Slide 39

Slide 39 text

Thank You!