**Lua でサーバー側に描画されるマルチプレイヤーゲーム(クライアントコードは不要)**

2026/01/05 4:54

**Lua でサーバー側に描画されるマルチプレイヤーゲーム(クライアントコードは不要)**

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Cleoseleneは、サーバー上でグラフィックスをレンダリングし、そのロジックをLuaスクリプティングで公開するマルチプレイヤーファーストのゲームエンジンです。プロジェクトは

main.lua
にある6つのコールバックで駆動されます:
init()
– 空間データベース(
api.new_spatial_db(cell_size)
)、物理世界(
api.new_physics_world(db)
)、サウンドなどをセットアップします。
update(dt)
– 物理シミュレーションを進め、衝突イベントを処理し、ゲームロジックを実行します。
draw(session_id)
– 画面をクリアし、色を設定してプレイヤー統計を表示し、可視エンティティ(
db:query_rect
で空間DBからクエリ)を描画します。
on_connect(session_id)
,
on_disconnect(session_id)
,
on_input(session_id, key_code, is_down)
– セッションライフサイクルを処理し、JavaScriptキーコード(37=Left, 38=Up, 39=Right, 40=Down, 32=Space, 90=Z)をゲーム入力状態にマップします。
エンジンは固定の仮想座標系 800 × 600 を使用し、出力を自動でスケーリングして解像度とアスペクト比を任意のディスプレイで保ちます。空間ハッシュは円形および線分エンティティをサポートし、ユニークIDにより高速な範囲検索・矩形検索・レイ検索が可能です。物理ボディには速度、重力、および衝突コールバックがあります。描画はシンプルなAPI呼び出し(
clear_screen
,
set_color
,
fill_rect
,
draw_line
,
draw_text
)とサウンド制御関数(
load_sound
,
play_sound
,
stop_sound
,
set_volume
)で行われます。
ナビゲーショングラフ(
api.new_graph()
)はノード/エッジの追加を許可し、
find_path(start, end)
でA*経路探索を実施します。
ドキュメント内のサンプルコードでは、セルサイズ250の空間DBを初期化し、物理世界を作成し、ジャンプ音をロードし、各フレームで物理演算をステップさせ、衝突処理とプレイヤー体力描画を行う例が示されています。
まだプレビュー段階ですが、Cleoseleneはネットワークとレンダリングをサーバーにオフロードし、開発者がLuaでゲームプレイロジックに集中できるようにすることでマルチプレイヤー開発を簡素化することを目指しています。将来のリリースでは物理詳細、衝突処理、およびナビゲーション機能を深化させ、インディスタジオがネットワークタイトルをプロトタイピングできる速度を向上させる予定です。

本文

⚠️ アクティブ開発中
Cleoselene は現在初期プレビュー段階にあります。
本格的なプロジェクトや本番環境でご利用になる前に、必ず help@cleoselene.com までお問い合わせください。


Cleoselene マニュアル

Lua スクリプトを採用したマルチプレイヤー優先型サーバーサイドレンダリングゲームエンジンです。

ゲーム構成

最小限のゲームスクリプト(

main.lua
)は、以下のコールバックを実装する必要があります。

-- サーバー起動時に一度だけ呼び出されます
function init()
    -- 物理エンジンやアセットの初期化、状態設定
    db   = api.new_spatial_db(250)
    phys = api.new_physics_world(db)

    api.load_sound("jump", "assets/jump.wav")
end

-- 毎サーバーフレーム(通常は 30 TPS)で呼び出されます
function update(dt)
    -- 物理シミュレーションを進める
    phys:step(dt)

    -- 衝突処理
    local events = phys:get_collision_events()
    for _, pair in ipairs(events) do
        -- ゲームロジック(ダメージ、スコアなど)をここで扱う
    end
end

-- 接続している各クライアントのフレームを生成するために呼び出されます
function draw(session_id)
    api.clear_screen(20, 20, 30)

    -- プレイヤー固有のビュー(カメラ、HUD)を描画
    local p = players[session_id]
    if p then
        api.set_color(255, 255, 255)
        api.draw_text("HP: " .. p.hp, 10, 10)
        -- db:query_rect を使って可視領域内のエンティティを描画
    end
end

-- ネットワークイベント
function on_connect(session_id)
    print("Player joined: " .. session_id)
    -- プレイヤーエンティティを生成
end

function on_disconnect(session_id)
    print("Player left: " .. session_id)
    -- エンティティを削除
end

function on_input(session_id, key_code, is_down)
    -- 入力処理(key_code は JS キーコード)
    -- 37=左, 38=上, 39=右, 40=下, 32=スペース, 90=Z
    if players[session_id] then
        players[session_id].inputs[key_code] = is_down
    end
end

API リファレンス

表示と座標

エンジンは 800 × 600 の固定仮想座標系を採用しています。

api.fill_rect
,
api.draw_line
などの描画コマンドはすべてこの座標系で動作します。
出力は自動的にユーザーの画面サイズに合わせてスケールされ、論理解像度とアスペクト比は保持されます。

メソッド説明
api.clear_screen(r, g, b)
背景色でフレームをクリアします。
api.set_color(r, g, b, [a])
現在の描画色を設定します。
api.fill_rect(x, y, w, h)
塗りつぶし長方形を描きます。
api.draw_line(x1, y1, x2, y2, [width])
線分を描画します。
api.draw_text(text, x, y)
指定位置にテキストを描画します。
api.load_sound(name, url)
URL/パス(スクリプトからの相対)から音声をプリロードします。
api.play_sound(name, [loop])
ロード済みの音声を再生します。
api.stop_sound(name)
再生中の音声を停止します。
api.set_volume(name, volume)
音量(0.0 – 1.0)を設定します。

空間データベース(ジオメトリ)

エンジンは高速な空間ハッシュグリッドを提供し、広域クエリを行います。

作成

local db = api.new_spatial_db(cell_size)  -- 例: 250
メソッド説明戻り値
db:add_circle(x, y, radius, tag)
円形エンティティを登録します。
id (int)
db:add_segment(x1, y1, x2, y2, tag)
線分(壁)を登録します。
id (int)
db:remove(id)
エンティティを削除します。
nil
db:update(id, x, y)
手動で位置を更新(テレポート)。
nil
db:get_position(id)
エンティティの (x, y) を取得します。
x, y

クエリ(センサー)

メソッド説明戻り値
db:query_range(x, y, r, [tag])
半径 r 内のエンティティ ID を取得します。
{id1, id2, …}
db:query_rect(x1, y1, x2, y2, [tag])
AABB 内のエンティティ ID を取得します(カリング用)。
{id1, id2, …}
db:cast_ray(x, y, angle, dist, [tag])
レイキャストを行います。
id, frac, hit_x, hit_y
または
nil

物理エンジン(シミュレーション)

剛体ダイナミクス、積分、衝突解決を担当します。

作成

local phys = api.new_physics_world(db)
メソッド説明
phys:add_body(id, props)
エンティティに物理特性を追加。
props
:
{mass=1.0, restitution=0.5, drag=0.0}
など。
phys:set_velocity(id, vx, vy)
速度を設定します。
phys:get_velocity(id)
vx, vy
を取得します。
phys:set_gravity(x, y)
グローバル重力ベクトルを設定します。
phys:step(dt)
シミュレーションを進め、衝突解決と DB の更新を行います。
phys:get_collision_events()
前回ステップ以降の衝突リストを返します:
{{idA, idB}, …}

グラフナビゲーション(パスファインディング)

カスタムグラフ上で動作するネイティブ A* 実装です。

メソッド説明
nav = api.new_graph()
新しいナビゲーショングラフを生成します。
nav:add_node(id, x, y)
ノードを追加します。
nav:add_edge(u, v)
2つのノード間にエッジ(接続)を作ります。
nav:find_path(start, end)
最短経路となるノード ID のリストを返します。

同じ日のほかのニュース

一覧に戻る →

2026/01/05 6:01

北ダコタ州法は、石炭業界の弁護士の名前に由来する偽の「クリティカルミネラル」を一覧化しています。

## Japanese Translation: **改善された要約** 記事には「State(州)」「Zip Code(郵便番号)」「Country(国)」の3つのセクション見出しのみが含まれています。これらの見出しの下に追加のテキスト、説明、または例はありません。

2026/01/05 5:17

**Show HN: AWS用ターミナル UI**

## Japanese Translation: > **概要:** > tawsはRustで書かれた軽量なターミナルUIで、k9sに触発されており、ユーザーがAWSリソースを迅速かつ効率的に管理できるようにします。リアルタイム更新、Vim風ナビゲーション(`k/j/↑/↓`, `g/G`)、リソース操作(例:EC2の開始/停止/終了は`s/S/T`)、JSON/YAMLビュー、フィルタリング、ファジー補完、およびコロン(`:`)で呼び出すリソースピッカーをサポートします。 > このツールは30個の主要AWSサービス(典型的な使用率の95%以上)にわたって動作し、マルチプロファイル/マルチリージョンナビゲーション(`p`, `R`)が可能です。Homebrew(`brew install huseyinbabal/tap/taws`)でインストールできるほか、macOS、Linux、Windows向けに事前構築済みバイナリをダウンロードして使用できます。macOS/Linux用のクイックインストールスクリプトも提供されています。 > AWS認証情報は`aws configure`、環境変数、またはIAMロールで供給でき、必要最低限の権限はDescribe*とList*です。本プロジェクトはMITライセンスで配布されており、新しいサービスを追加する前にディスカッションが奨励されています。将来のリリースではサービス対応範囲の拡大を目指し、IAM権限ギャップ、ページネーション制限、グローバルサービスデフォルトなど既知の問題にも対処します。 この改訂された概要は主要なポイントすべてを網羅しており、元の内容に忠実で、読者にとって明確かつ簡潔な概要を提供します。

2026/01/05 4:48

**Claude Code On‑the‑Go** (クレオード・コード・オンザゴー)

## Japanese Translation: **(修正版)** > 著者は、iPhone 上で 6 つの Claude Code エージェントを実行する、コスト管理済みかつモバイルフレンドリーなワークフローを構築します。 > > * **Vultr VM**(Silicon Valley の `vhf‑8c‑32gb`)を 2 本のスクリプト(`vm-start`、`vm-stop`)で起動・停止し、iOS ショートカットから呼び出します。VM は稼働時に約 **$0.29 / hr(約 $7/日)** の費用がかかります。 > > * 接続は **Tailscale のプライベートネットワーク** を介し、**Termius + mosh** で行い、Wi‑Fi / モバイル通信の切り替えや電話機のスリープ時でも継続する頑健な SSH セッションを実現します(SSH エージェントは転送されないため、GitHub 認証は tmux 内の通常キーで行います)。 > > * ログイン時にシェルが自動的に **tmux** にアタッチします(`if [[ -z "$TMUX" ]]; then tmux attach -t main || tmux new -s main fi`)、再接続時も状態を保持します。 > > * 各 Claude エージェントは、別々の Git 作業ツリー・ブランチに紐付けられた独自の tmux ウィンドウで実行されます。ポート番号は `django_port = 8001 + (hash_val % 99)` により決定的に割り当てられ、`hash_val = sum(ord(c) for c in branch_name)` です。 > > * `~/.claude/settings.json` の **PreToolUse フック** はタスク完了時に Poke にプッシュ通知を送信します。質問は `jq` で抽出し、メッセージを構築して `curl` で送信します。 > > * 全体のセットアップは、セキュリティ上隔離された消耗性 VM を使用し、潜在的な無制限利用を日次コストキャップ(約 $7)に限定しています。 > > * 開発者は電話で 10–20 分程度の Claude タスクを開始し、その間他の作業を行いながら通知が来るまで待つことができます。 この修正版要約は、すべての主要ポイントを完全に反映し、推論を避け、曖昧な表現を排除して情報を明確に提示しています。