土曜日, 12月 20, 2025
No menu items!
ホーム ブログ ページ 4603

「小島監督ゲームランキング発表!『MGS』1位に!」

本日、2025年6月23日に公開された記事では、小島秀夫監督のゲーム作品ランキングがIGN US編集部によって発表されました。このランキングは、待望の続編『DEATH STRANDING 2: ON THE BEACH』の発売を記念したもので、彼がディレクションやデザインを手がけた作品が対象となっています。

ランキングの概要

  1. 『METAL GEAR SOLID』
  2. 『METAL GEAR SOLID 3 SNAKE EATER』
  3. 『METAL GEAR SOLID 2 SONS OF LIBERTY』
  4. 『P.T.』
  5. 『METAL GEAR SOLID V: THE PHANTOM PAIN』と「GROUND ZEROES」
  6. 『METAL GEAR SOLID PEACE WALKER』
  7. 『DEATH STRANDING』
  8. 『METAL GEAR』
  9. 『METAL GEAR SOLID 4 GUNS OF THE PATRIOTS』
  10. 『METAL GEAR 2 SOLID SNAKE』
  11. 『スナッチャー』
  12. 『ポリスノーツ』

ランキングの1位に輝いたのは、ゲームの歴史においても重要な位置を占める『METAL GEAR SOLID』です。この作品は、敵の視界を円錐型で表示する「ソリトンレーダー」や、サイコマンティスとのユニークなボス戦など、革新的なゲームプレイが評価されています。小島監督は、当時の技術的制約を乗り越え、ストーリー、視覚、そしてプレイ体験のすべてにおいて高評価を得ているとされています。

特に『P.T.』は、その完成されていない状態にもかかわらず、4位に位置づけられています。この作品はプレイアブルなティーザーとして、独特の恐怖感を味わえるものでしたが、完全版がリリースされなかったのが大きな悲劇とされています。

また、初代『DEATH STRANDING』は7位で、IGNはそのストーリーが非常に予言的であると評価しています。特に、新型コロナウイルスのパンデミック以前にリリースされたことで、今となってはそのテーマに対して深い考察が求められる作品です。

『DEATH STRANDING 2: ON THE BEACH』はPS5で6月26日に発表される予定です。今後の展開が非常に楽しみです。

IGNの記事で詳しく知る


画像もチェック

METAL GEAR SOLIDシリーズのスクリーンショット

この情報を通じて、小島監督の作品の魅力や影響力を改めて感じることができるのではないでしょうか。

🧠 編集部より:

この記事では、小島秀夫監督のゲーム作品に関するランキングが紹介されています。特に注目されるのは、1位に輝いた『METAL GEAR SOLID』です。このゲームがもたらした革新は、特にストーリーやゲームメカニクスの面で、ゲーム業界に大きな影響を与えました。

バックグラウンド

『METAL GEAR SOLID』は1998年に発売され、プレイヤーの選択に基づくステルスゲームプレイと、緻密なストーリー展開が特徴です。特にソリトンレーダーやサイコマンティスとの戦いなど、当時としては斬新なアイデアが多く、プレイヤーを驚かせました。

豆知識

  • 『P.T.』は、開発が中止となったホラーゲームのティーザーで、多くのファンから惜しまれています。リリースされなかったにも関わらず、その独特の雰囲気は今でも記憶に残っています。
  • 『DEATH STRANDING』は、オンラインで他のプレイヤーと繋がる独自のゲームプレイスタイルや、Apocalypticな世界観が話題になりました。特に、リアルな世界のつながりを描写している点が特筆されます。

リンク集

  • IGN USの記事では、ランキングの詳細や各ゲームの特徴が紹介されています。
  • 『DEATH STRANDING 2: ON THE BEACH』に関しては、重要な情報や最新ニュースが載った記事もチェックしてみてください。

このランキングの発表は、小島監督の影響力と彼の作品がどれほど多くの人々に感動を与えているかを再確認する良い機会です。ファンとしては、これからの新作にも期待が高まります。

  • キーワード: 小島秀夫

METAL GEAR SOLID をAmazonで探す

P.T. をAmazonで探す

DEATH STRANDING をAmazonで探す



※以下、出典元
▶ 元記事を読む

Views: 0

『WIND BREAKER』新グッズ登場!ラッキーくじで大人気アイテムをゲットしよう!

セガ ラッキーくじオンライン「WIND BREAKER」-STREET DANCE- 発売

2025年6月23日(月)より、TVアニメ『WIND BREAKER』をテーマにしたセガ ラッキーくじオンラインが販売開始されました。これまでとは一味違ったストリートダンスをテーマにしたキャラクターの描きおろしイラストを楽しむことができます。

商品の見どころ

本くじでは、ボウフウリンメンバーの桜遥や蘇枋隼飛がストリートダンススタイルの服装を着こなして登場します。普段とは異なる姿に、ファンの中には魅力を感じる方も多いことでしょう。

賞品ラインナップ

以下は、今回のくじで手に入る賞品一覧です:

  • A賞:マルチクロス

  • B賞:ぬいぐるみマスコット
    B賞:ぬいぐるみマスコット

  • C賞:アクリルスタンド
    C賞:アクリルスタンド

  • D賞:デフォルメアクリルスタンド
    D賞:デフォルメアクリルスタンド

  • E賞:アクリルキーホルダー
    E賞:アクリルキーホルダー

  • F賞:缶バッジ
    F賞:缶バッジ

マストバイキャンペーン

くじを10回引くと、好みのステッカーを選ぶことができるキャンペーンも開催しています。
マストバイキャンペーン:ステッカー

販売概要

  • 商品名:セガ ラッキーくじオンライン TVアニメ『WIND BREAKER』-STREET DANCE-
  • 販売期間:6月23日(月)11:00 ~ 7月28日(月)23:59
  • 価格:1回770円(税込)+送料660円(税込・初回購入時のみ)

詳しくは公式サイトでチェックしてください。

このくじは、ファンにとっては手に入れたいアイテムが目白押しの内容ですので、ぜひこの機会をお見逃しなく!

🧠 編集部より:

セガ ラッキーくじオンライン「WIND BREAKER」-STREET DANCE-についての補足説明

2025年6月23日(月)より順次発売中の「セガ ラッキーくじオンライン TVアニメ『WIND BREAKER』-STREET DANCE-」。このくじは、人気アニメ『WIND BREAKER』をテーマにした多彩な商品がラインナップされており、ファンにはたまらないアイテムが揃っています。

商品の魅力

  • 描き下ろしイラスト: 桜遥や蘇枋隼飛などのボウフウリンメンバーが、ストリートダンスをテーマにしたかわいい衣装で描かれています。これはアニメのシーンからインスパイアされたものと言われており、ファンはその違った一面を楽しむことができます。

  • ラインナップ:
    • A賞: マルチクロス
    • B賞: ぬいぐるみマスコット
    • C賞: アクリルスタンド
    • D賞: デフォルメアクリルスタンド
    • E賞: アクリルキーホルダー
    • F賞: 缶バッジ

各賞は、参加者の運によって手に入るため、コレクターやファンにとって特別な魅力があります。

スペシャルキャンペーン

また、10回くじを引くごとに選べる特別なステッカーも用意されています。これにより、ファンは自分好みのアイテムをカスタマイズ可能です。

購入情報

  • 販売期間: 2025年6月23日(木)11:00~7月28日(月)23:59
  • 価格: 1回770円(税込)+送料660円(税込・初回購入時のみ)

購入や詳細情報は、公式サイトをご確認ください。

豆知識

『WIND BREAKER』は、ストリートダンスや若者文化をテーマにしており、特にダンスや運動が好きな人たちからの支持が厚いです。アニメの成功は、視聴者だけでなく、ダンスコミュニティにも多大な影響を与えています。

このように、セガのラッキーくじは、アニメファンやコレクターにとっての楽しみを広げてくれる素敵な企画です。興味のある方は、ぜひ参加してみてください!

  • キーワード: WIND BREAKER

マルチクロス をAmazonで探す
ぬいぐるみマスコット をAmazonで探す
アクリルスタンド をAmazonで探す



※以下、出典元
▶ 元記事を読む

Views: 0

「イラン核施設にバンカーバスターの真実」

2025年6月22日、アメリカ軍はイランの核関連施設に対する攻撃を行いました。この攻撃には、地下深くに建設された施設を効果的に攻撃するために、「バンカーバスター」と呼ばれる特殊な爆弾が使用されました。これにより、地下60メートルまで潜入できる「GBU-57」が初めて実戦で使用されたことが注目されています。

バンカーバスターの仕組みと特長

1. 対象に対する高い精密性

バンカーバスターは単に大きく重い爆弾ではなく、特定の設計によって地下の構造物を狙った攻撃が可能です。具体的には、重力加速度を感知する信管と、時間差で起爆する信管の組み合わせにより、地面に接触した後に地下深くに潜り込んでから爆発します。

2. 最新技術の採用

GBU-57の全長は約6.25メートル、重さは約1万4000kgです。外装には硬化フェロコバルト合金が使用されており、地中の鉄筋コンクリートを貫通する能力を持っています。また、爆薬ユニットは2267kgの重さを誇り、内部には軍用レベルのGPSも装備されています。

攻撃の方法

アメリカ軍はB2ステルス爆撃機からGBU-57を投下し、GPSを利用して正確に目標を捕捉します。攻撃は高高度から行われ、爆弾は目的地に向かって落下後、地下深くまで潜り込む仕組みです。最終的に、目標地点に達することで大きな損害を与えるのです。

経済的側面

GBU-57の開発費用は推定4億ドルから5億ドル(約590億円~730億円)とされ、1ユニットあたりの生産価格は350万ドル(約5億1000万円)です。

下記の画像はこの新型爆弾に関する詳細を示しています。

GBU-57の爆弾 バンカーバスターの構造 投下手順 爆発のタイミング

このように、バンカーバスターは現代の軍事技術を象徴するものであり、その効果的な使用は今後の国際情勢に大きな影響を与えることが予想されます。

🧠 編集部より:

バンカーバスターについての補足説明

アメリカ軍が使用した「バンカーバスター」は、特に地下施設の破壊を目的とする高度な爆弾です。これには、堅固な建造物を貫通するための強力な設計がなされています。なぜこの爆弾が特に効果的なのか、そのメカニズムを見ていきましょう。

バンカーバスターのメカニズム

  1. 設計と素材:

    • GBU-57と呼ばれるバンカーバスターは、強固なフェロコバルト合金で作られ、全体の80%が外装に使用されています。この重さが貫通力を高めます。
  2. 深度の貫通能力:

    • GBU-57は地下60mまで潜って爆破する能力を持ち、これにより地下施設への直接的な攻撃が可能です。過去の爆弾と比べても、最も深く潜れる設計になっています。
  3. 爆発のメカニズム:
    • 通常の爆弾は地表で爆発しますが、GBU-57は重力センサーと時間差信管を利用して、地表に接触した後に地下で爆発します。

豆知識

  • 歴史的背景: バンカーバスター技術は1970年代に開発され、初めての実戦投入は任務の特性上、非常に高い精度と効率を求められます。また、GBU-28など、先代のモデルでは約6mまでの貫通能力しか持たなかったため、この進化は特に注目されています。

  • 開発費用: GBU-57の開発費は約4億~5億ドルとされ、1つあたりの製造コストは約350万ドルです。高コストではありますが、その戦略的価値は計り知れないものがあります。

まとめ

バンカーバスターはその特異な設計により、通常の爆弾では難しい地下施設への攻撃を可能にしました。今後もこの技術がどのように進化し、戦争の戦略に影響を与えていくのか、注目が集まります。

関連リンク

興味がある方は、これらのリンクをチェックして、より詳しく学んでみてください!


  • キーワード: バンカーバスター

    この爆弾は、イランの地下核関連施設への攻撃に用いられ、その高い貫通力で知られています。GBU-57は最新のモデルで、地下60メートルまで攻撃可能です。

バンカーバスターをAmazonで探す GBU-57をAmazonで探す 戦略爆撃機B2をAmazonで探す

※以下、出典元 ▶ 元記事を読む

Views: 0

「Z世代注目!“冷蔵庫タバコ”の魅力」

📌 ニュース:

Z世代の新たな娯楽“冷蔵庫のタバコ”とは?

午後の特定の時間、気分転換を求めるZ世代に人気なのが、
“冷蔵庫のタバコ”。これは、冷えたダイエットコークを指す新しいスラングです。

このトレンドは、TikTokユーザーの投稿をきっかけに広まり、
「冷蔵庫のタバコ」として多くの共感を得ました。
仕事や勉強の合間に、依存性のあるご褒美として楽しむ様子が見られます。

ダイエットコークはパーラメントに、
通常のコカ・コーラはマルボロというように、様々な飲み物が
特定のタバコに例えられる傾向も見られます。

この背景には、ノスタルジーやポップカルチャーの変化が影響しており、
「冷蔵庫のタバコ」は新たなトレンドとして注目されています。

  • この記事のポイントを以下のようにまとめました。

    1. 新しいスラング「冷蔵庫のタバコ」🥤
      Z世代の間で流行中の“冷蔵庫のタバコ”は、実際のタバコではなく、キンキンに冷えたダイエットコークを指します。特定の時間に気分転換をしたいときに求められる新しいご褒美となっています。

    2. TikTokでのバズ✨
      TikTokユーザーの投稿をきっかけに広まったこのトレンドは、瞬く間に350万再生を超える人気を博しました。ユーザーたちからは、「すごくリアル」や「これで一日を乗り切れる」という共感の声が寄せられています。

    3. 飲み物とタバコのブランドに見立てるトレンド🔄
      ダイエットコークが特定のタバコブランドに例えられる流れが進行中です。コーラはマルボロ、コークゼロはアメリカンスピリットなど、飲料のイメージが喫煙文化と融合しています。これは、ポップカルチャーの変化の一環とも考えられています。


※以下、出典元
▶ 元記事を読む

Views: 0

このBaldur’s Gate3の成果は非常にまれで、Steamプレーヤーの2%だけがそれを持っています



最も希少な成果 バルドゥールのゲート3 プレーヤーの約2%によってしか稼いでいませんが、非常にとらえどころのないことは非常に奇妙なものです:Busker。それを視野に入れるために、 より多くのプレイヤーが功績を獲得しています、 のために 名誉モードでゲームを破りますBG3最も難しい挑戦。 Buskerはかなり無害な功績であり、路上でのパフォーマンスからコインを獲得することをプレイヤーに要求するだけです。


続きを見る


🧠 編集部の感想:
「Baldur’s Gate 3」の成果がプレイヤーのわずか2%にしか達成されていないのは、ゲームの深さを物語っています。特に「Busker」のような軽い成果が難しいものに埋もれてしまうのが興味深いです。プレイヤーが多くの挑戦に取り組む中で、このユニークな成果がどのように評価されるか、今後の展開が楽しみです。

Views: 0

JBLが楽天で最大20倍ポイント!お得なイヤホン&ヘッドホン♪

2025年6月23日、ハーマンインターナショナルが運営するJBL公式楽天市場店が注目のキャンペーンを発表しました。現在、同店ではイヤホンやヘッドホン、Bluetoothスピーカー、ターンテーブルなどの音響製品が対象で、最大20倍のポイント還元が行われています。

キャンペーンの詳細

  • 期間: 2025年6月27日(金)9時59分まで
  • 対象商品: イヤホン、ヘッドホン、Bluetoothスピーカー、ターンテーブルなど

ポイント還元のメリット

このキャンペーンは特に、音楽を愛する人々や高品質な音響機器を求める方にとって魅力的です。通常の購入で得られるポイントが大幅に増えるため、次回の買い物や他の製品の購入が非常にお得になります。

まとめ

JBL公式楽天市場店のこのキャンペーンは、音楽を楽しむ上で欠かせないアイテムを手に入れる絶好の機会です。興味のある方は、期限に注意して早めにチェックしてみてください。音楽体験をさらに豊かにするアイテムが待っています!

🧠 編集部より:

JBL公式楽天市場店のキャンペーンについて

ハーマンインターナショナルが運営するJBL公式楽天市場店では、今、特別なキャンペーンを行っています。このキャンペーンでは、イヤホン、ヘッドホン、Bluetoothスピーカー、さらにはターンテーブルなど、さまざまなオーディオ製品が対象です。特に最大20倍のポイント還元が受けられるため、買い物をする絶好のチャンスです。

キャンペーン概要

  • 期間: 6月27日(金)9時59分まで
  • 対象商品: イヤホン、ヘッドホン、Bluetoothスピーカー、ターンテーブルなど

音質にこだわる人に

JBLは、特に音質へのこだわりが強く、さまざまなジャンルに合った製品を展開しています。例えば、JBLのヘッドホンは、外部音を遮断し、臨場感あふれるサウンドを提供します。また、Bluetoothスピーカーはポータブルで、アウトドアやパーティーでも手軽に使用できるため、多くのユーザーに支持されています。

豆知識

JBLは1946年に設立され、長い歴史を持つオーディオブランドです。音楽業界のイベントや映画などでも多く使用されており、その音質は業界でも高く評価されています。特に、JBLのスピーカーはコンサートやフェスでよく見かけるアイテムです。

関連リンク

音楽愛好者にとっては見逃せないキャンペーンですので、ぜひこの機会を利用してお得にオーディオ製品を手に入れてみてください!

  • 「キャンペーン」

イヤホン をAmazonで探す
BTスピーカー をAmazonで探す
ターンテーブル をAmazonで探す



※以下、出典元
▶ 元記事を読む

Views: 0

未熟でもコードレビューをするべき3つの理由



未熟でもコードレビューをするべき3つの理由

はじめに
私のエンジニアとしての経験はもうすぐ満2年。
まだまだ経験が浅い立場ではありますが、これまでに何度か他の方のコードレビューを任される機会がありました。
最初は「自分がレビューなんてしていい…



Source link

Views: 0

Dart client for Genkit: Flutter/Dart から Genkit フローを呼び出す


genkit-dart

はじめに

私は Firebase が好きで、フロントエンドフレームワークとしては、Flutter を採用することが多いです。

Google I/O 2024 以降、Genkit を継続的に触り続けています。
Genkit は、サーバーサイドで AI を活用した一連の処理を フロー (Flow) として簡単に定義できる、Firebase チームによって開発された Google 製のオープンソースフレームワークです。

しかし、サーバーで定義したフローを、クライアントである Dart/Flutter アプリから呼び出すには、ひと手間必要でした。
このギャップを埋めるのが、今回開発した Dart client for Genkit パッケージです。(ベータ版)

ライブラリ概要

上記でも記載の通り、本ライブラリは、サーバー上にデプロイされた Genkit フロー(Cloud Run functions, Cloud Run, GKE などのプラットフォームに公開された Web API)を簡単にコールするための Genkit 専用クライアントライブラリ であり、Dart で Genkit フローを実装するものではありません。

従来の課題

これまでは、Dart/Flutter から Genkit フローを呼び出すには、いくつかのお作法に沿って、手作業で HTTP クライアントを実装する必要がありました。

例えば、以下は HTTP クライアントに dio を使って、Genkit で定義した画像生成フローを呼び出す、これまでの一般的なコードです。

https://github.com/nozomi-koborinai/flutter-imagen3/blob/53926cf63a840f4c0d96a00ec231eff2e11f21f3/lib/data/genkit_client.dart#L25-L43

このコードには、いくつか課題があります。

  • リクエストを送る際には入力を {'data': ...} でラップし、レスポンスを受け取った際には response.data['result'] から結果を取り出す必要があります。これは Genkit サーバー側固有のルールであり、クライアント側で実装者が毎回意識するのは面倒ですし、間違いの元にもなります。

  • Genkit フローが増えるたびに、似たような HTTP リクエストのコードを書くことになります。認証ヘッダーの付与などを共通化するにも、自分で仕組みを作る必要がありました。

  • 上記は単純なリクエストの例ですが、リアルタイムでデータを受け取るストリーミング処理を実装しようとすると、Server-Sent Events (SSE) プロトコルのレスポンスを自力でパースする必要があり、コードはさらに複雑になります。

他のクライアントとの統一性

このライブラリは、公式で提供されている Next.js や Angular 向けのクライアントとインターフェースを合わせて設計されています。

コア設計

このライブラリがどのようにして、Genkit フローの呼び出しを抽象化しているのか、その設計思想や実装内容を紹介します。

主要な構成要素

ライブラリは、主に 3 つのクラスで構成されています。

1. RemoteAction クラス

すべての操作の起点となる、中心的なクラスです。
リモート(サーバー上)の Genkit フローを Dart の世界で表現するオブジェクトと考えることができます。

class RemoteActionO, S> {
  final String _url;
  final MapString, String>? _defaultHeaders;
  final http.Client _httpClient;
  final O Function(dynamic jsonData) _fromResponseData;
  final S Function(dynamic jsonData)? _fromStreamChunkData;

  
}

ジェネリクスによって、型安全な操作を保証します。

  • O (Output): フローが完了したときに受け取る、最終的なレスポンスの型
  • S (Stream): ストリーミング実行時に、途中で送られてくるチャンクデータの型(ストリーミングを使わない場合は void を指定)

2. FlowStreamResponse

ストリーミング操作の戻り値は、Record 型 FlowStreamResponse で定義されています。

typedef FlowStreamResponseO, S> = ({FutureO> response, StreamS> stream});

これにより、response(最終結果の Future)と stream(途中経過の Stream)の両方に、1 つのオブジェクトから型安全にアクセスでき、直感的なコーディングが可能になります。

3. GenkitException クラス

Genkit フローがエラーを返した場合、ライブラリはそれを GenkitException としてスローします。
HTTP ステータスコードや詳細なエラー情報が含まれているため、クライアント側での柔軟なエラーハンドリングをサポートします。

class GenkitException implements Exception {
  final String message;
  final int? statusCode;
  final String? details;
  final Exception? underlyingException;
  final StackTrace? stackTrace;

  const GenkitException(
    this.message, {
    this.statusCode,
    this.details,
    this.underlyingException,
    this.stackTrace,
  });
}

ストリーミング実装について

このライブラリの最も強力な機能の 1 つが、ストリーミングのサポートです。
この裏側では Server-Sent Events (SSE) プロトコルが使われています。

Genkit のストリーミングエンドポイントは、下記のような形式でデータを断続的に送り出してきます。

data: {"message": {"text": "Hello"}}

data: {"message": {"text": " World"}}

data: {"result": "Hello World"}

このままでは扱いにくいため、ライブラリ内部では、まず SSE プロトコルで定められたいくつかの定数を使って、生データを解析していきます。


const flowStreamDelimiter = '\n\n';
const sseDataPrefix = 'data: ';
  • flowStreamDelimiter

    • 各メッセージブロックは、2 つの改行文字 \n\n で区切られる
    • この定数を使って、ストリームから個々のメッセージを正確に切り出す
  • sseDataPrefix

    • SSE の仕様では、メッセージ本体の各行は data: という接頭辞で始まる必要がある
    • この定数は、その接頭辞を識別し、取り除くために使用する

これらの定数を用いて、ライブラリはデータストリームを Dart の Stream オブジェクトに変換する、以下のような処理を行っています。

_streamInternal メソッド内の listen コールバックから抜粋

var buffer = '';

subscription = streamedResponse.stream.transform(utf8.decoder).listen(
  (decodedChunk) {
    
    buffer += decodedChunk;

    
    while (buffer.contains(flowStreamDelimiter)) {
      final endOfChunk = buffer.indexOf(flowStreamDelimiter);
      
      final chunkData = buffer.substring(0, endOfChunk);
      
      buffer = buffer.substring(endOfChunk + flowStreamDelimiter.length);

      
      if (!chunkData.startsWith(sseDataPrefix)) {
        continue;
      }
      
      final jsonData = chunkData.substring(sseDataPrefix.length);
      if (jsonData.isEmpty) continue;

      try {
        final parsedJson = jsonDecode(jsonData);

        
        if (parsedJson is MapString, dynamic>) {
          if (parsedJson.containsKey('message')) {
            
            if (!streamController.isClosed) {
              streamController.add(parsedJson['message']);
            }
          } else if (parsedJson.containsKey('result')) {
            
            if (!responseCompleter.isCompleted) {
              responseCompleter.complete(parsedJson['result']);
            }
          } else if (parsedJson.containsKey('error')) {
            
            
            
          }
        }
      } on FormatException catch (e, s) {
        
        
      }
    }
  },
  onDone: () {
    
  },
  onError: (e, s) {
    
  },
);

この実装により、Dart/Flutter アプリの実装者は SSE の複雑な仕様を意識することなく、await for を使って直感的に Genkit フローのストリーミングデータを扱うことが可能となります。

使い方

ここからが本題です。
Dart client for Genkit のパッケージを自プロジェクトからどうやって使用するかを紹介していきます。

基本的なセットアップ

install

dart pub add genkit
or
flutter pub add genkit

impor

import 'package:genkit/genkit.dart';

1. 最もシンプルな String → String のフロー呼び出し

はじめに、最も基本的な例として、文字列を入力として受け取り、文字列を返すフローを呼び出してみます。

Genkit JS(サーバー)側

まず、サーバー側で以下のような、string 型の入力と出力を持つ Genkit フローが定義されているとします。

export const simpleStringFlow = ai.defineFlow(
  {
    name: `simple-string`,
    inputSchema: z.string(),
    outputSchema: z.string(),
  },
  async (input) => {
    const response = await ai.generate({ prompt: input });
    return response.text;
  }
);

Dart(クライアント)側

このフローを Dart から呼び出すには、defineRemoteAction を使ってクライアントを定義します。
フローのエンドポイント URL と、レスポンスを期待する型に変換するための fromResponse 関数を渡すだけで、あとは定義したアクションを関数のように実行できます。

import 'package:genkit/genkit.dart';

void main() async {
  
  final simpleStringAction = defineRemoteAction(
    url: 'https://your-service.com/simpleString',  
    fromResponse: (json) => json as String,  
  );

  
  try {
    final response = await simpleStringAction(
      input: 'Hello Dart client!',
    );
    print('Response: $response');
  } on GenkitException catch (e) {
    print('Genkit Error: ${e.message}');
  }
}

2. 型付きオブジェクトを使用した場合

次に、より実践的な例として、型付けされたオブジェクトを送受信する方法を見ていきましょう。json_serializable のようなライブラリと組み合わせることで、型安全性を維持したまま、複雑なデータを扱うことができます。

スキーマ定義(json_annotation を使用)

まず、クライアントとサーバーで共通のデータ構造を、Dart のクラスとして定義します。
ここでは json_serializable を使い、toJson / fromJson を自動生成します。

import 'package:json_annotation/json_annotation.dart';

part 'my_schemas.g.dart';

()
class MyInput {
  final String message;
  final int count;

  MyInput({required this.message, required this.count});

  factory MyInput.fromJson(MapString, dynamic> json) =>
      _$MyInputFromJson(json);
  MapString, dynamic> toJson() => _$MyInputToJson(this);
}

()
class MyOutput {
  final String reply;
  final int newCount;

  MyOutput({required this.reply, required this.newCount});

  factory MyOutput.fromJson(MapString, dynamic> json) =>
      _$MyOutputFromJson(json);
  MapString, dynamic> toJson() => _$MyOutputToJson(this);
}

Genkit JS(サーバー)側

サーバー側では Zod を使って Dart 側のクラスに対応するスキーマを定義します。

export const processObjectFlow = ai.defineFlow(
  {
    name: `process-object`,
    inputSchema: z.object({
      message: z.string(),
      count: z.number(),
    }),
    outputSchema: z.object({
      reply: z.string(),
      newCount: z.number(),
    }),
  },
  async (input) => {
    const response = await ai.generate({
      prompt: input.message,
    });

    const newCount = input.count * 2;

    return {
      reply: response.text,
      newCount,
    };
  }
);

Dart(クライアント)側

defineRemoteActionfromResponse に、先ほど定義したクラスの fromJson ファクトリコンストラクタを渡します。
これにより、クライアントは受け取った JSON を自動的に MyOutput オブジェクトに変換します。
呼び出し時には MyInput オブジェクトを渡すだけで、ライブラリが内部で JSON への変換を行います。

import 'package:genkit/genkit.dart';
import 'schemas/my_schemas.dart';

void main() async {
  final processObjectAction = defineRemoteActionMyOutput, void>(
    url: 'https://your-service.com/processObject',
    fromResponse: (json) => MyOutput.fromJson(json),
  );

  
  try {
    final response = await processObjectAction(
      input: MyInput(message: 'Hello Genkit!', count: 20),
    );
    print('Response: ${response.reply}, New Count: ${response.newCount}');
  } on GenkitException catch (e) {
    print('Error: ${e.message}');
  }
}

3. ストリーミングフロー

ストリーミング処理は、このライブラリの主要な機能です。
生成 AI からのレスポンスのように、サーバーからのデータを断続的に受け取りたい場合に役立ちます。

Genkit JS(サーバー)側

サーバー側では、streamSchemastreamingCallback を使って、ストリーミング用の Genkit フローを定義します。

export const streamObjectsFlow = ai.defineFlow(
  {
    name: `stream-objects`,
    inputSchema: z.object({
      prompt: z.string(),
    }),
    outputSchema: z.object({
      text: z.string(),
      summary: z.string(),
    }),
    streamSchema: z.object({
      text: z.string(),
      summary: z.string(),
    }),
  },
  async (input, streamingCallback) => {
    if (!streamingCallback) {
      throw new Error(`Streaming callback not provided for a streaming flow.`);
    }

    const { stream, response } = ai.generateStream({
      prompt: input.prompt,
    });

    let accumulatedText = ``;

    for await (const chunk of stream) {
      if (chunk.text) {
        accumulatedText += chunk.text;

        const streamChunk = {
          text: chunk.text,
          summary: `Processing: ${accumulatedText.slice(0, 50)}...`,
        };

        streamingCallback(streamChunk);
      }
    }

    const finalResponse = await response;
    const finalOutput = {
      text: finalResponse.text,
      summary: `Completed processing of: "${input.prompt}"`,
    };

    return finalOutput;
  }
);

Dart(クライアント)側

クライアント側では stream() メソッドを呼び出します。
これにより、最終結果の Future と途中経過の Stream を持つ FlowStreamResponse が返されます。
await for 構文を使えば、SSE の複雑さを意識することなく、サーバーからのストリームデータを簡潔に扱うことができます。

import 'package:genkit/genkit.dart';
import 'schemas/stream_schemas.dart';

void main() async {
  
  final streamObjectsAction = defineRemoteActionStreamOutput, StreamOutput>(
    url: 'https://your-service.com/streamObjects',
    fromResponse: (json) => StreamOutput.fromJson(json),      
    fromStreamChunk: (json) => StreamOutput.fromJson(json),  
  );

  try {
    
    final (:stream, :response) = streamObjectsAction.stream(
      input: StreamInput(prompt: 'What is Genkit?'),
    );

    
    print('Streaming chunks:');
    await for (final chunk in stream) {
      print('Chunk: ${chunk.text}');
    }

    
    final finalResult = await response;
    print('Final Response: ${finalResult.text}');
  } on GenkitException catch (e) {
    print('Error: ${e.message}');
  }
}

4. 認証ヘッダーの送信

実際のアプリケーションでは、認証が不可欠です。
このライブラリでは、HTTP ヘッダーを柔軟に設定することで、認証付きのフロー呼び出しを簡単に行えます。

Genkit JS(サーバー)側

例として、Firebase Authentication の匿名認証済みユーザーのみがフローを実行できる、というポリシーをサーバー側で設定します。

import { onCallGenkit } from "firebase-functions/https";
import { googleAIapiKey } from "./genkit";

import { processObjectFlow } from "./flows/process-object-flow";
import { streamObjectsFlow } from "./flows/stream-objects-flow";
import { simpleStringFlow } from "./flows/simple-string-flow";

const opts = {
  secrets: [googleAIapiKey],
  region: `asia-northeast1`,
  cors: true,
  authPolicy: (auth: any) => {
    
    return auth?.token?.firebase?.sign_in_provider === `anonymous`;
  },
};


export const simpleString = onCallGenkit(opts, simpleStringFlow);
export const processObject = onCallGenkit(opts, processObjectFlow);
export const streamObjects = onCallGenkit(opts, streamObjectsFlow);

Dart(クライアント)側

クライアント側では、Firebase Authentication SDK などで取得した ID トークンを、Authorization ヘッダーに含めてリクエストします。defineRemoteActiondefaultHeaders に設定すれば、そのインスタンスからのリクエストすべてに、このヘッダーが自動で付与されます。

import 'package:genkit/genkit.dart';
import 'package:firebase_auth/firebase_auth.dart';

void main() async {
  
  final user = FirebaseAuth.instance.currentUser;
  final idToken = await user?.getIdToken();

  
  final simpleStringAction = defineRemoteAction(
    url: 'https://your-service.com/simpleString',
    fromResponse: (json) => json as String,
    defaultHeaders: {
      'Authorization': 'Bearer $idToken',
    },
  );

  
  
  final response = await simpleStringAction(
    input: 'Hello Dart client!',
  );
  print('Response: $response');
}

リクエスト単位でのヘッダー設定

defaultHeaders に加えて、リクエストごとにヘッダーを動的に設定することも可能です。
call()stream() メソッドの headers 引数で指定することで、リクエスト ID を付与するなどの柔軟な対応ができます。

import 'package:genkit/genkit.dart';

void main() async {
  final remoteAction = defineRemoteAction(
    url: 'https://your-service.com/simpleString',
    fromResponse: (json) => json as String,
    defaultHeaders: {
     'Authorization': 'Bearer your-token',
     'X-Client-Type': 'flutter',
    },
  );

  
  final response1 = await remoteAction(
    input: 'First request',
    headers: {
      'X-Request-ID': 'req-001',
      'X-Priority': 'high',
    },
  );

  
  final response2 = await remoteAction(
    input: 'Second request',
    headers: {
      'X-Request-ID': 'req-002',
      'X-Priority': 'normal',
    },
  );
}

Flutter との組み合わせ

Dart client for Genkit を Flutter で使用する際のサンプルアプリも作ってみました。

サンプルアプリ

https://www.youtube.com/watch?v=AfsGlEh9tR4

サンプルアプリの実装詳細はこちらをご覧ください。
処理の流れをイメージしやすいように、Flutter (クライアント側)だけでなく、Genkit フロー(サーバー側)のコードも含めています。

Tips

今回のサンプルでは、GenkitClient という自前クラスを用意し、そこに、Dart client for Genkit を経由した Genkit フロー呼び出しを隠蔽しています。

※ クリーンアーキテクチャ、オニオンアーキテクチャ、レイヤードアーキテクチャの文脈でいうところのインフラストラクチャ層を担当させるイメージです。

class GenkitClient {
  GenkitClient();

  final baseUrl = 'https://region-project-name.cloudfunctions.net';

  
  
  
  FutureMyOutput> callProcessObjectAction({
    required String idToken,
    required String message,
    required int count,
  }) async {
    try {
      final remoteAction = defineRemoteActionMyOutput, void>(
        url: '$baseUrl/processObject',
        fromResponse: (json) => MyOutput.fromJson(json),
        defaultHeaders: {'Authorization': 'Bearer $idToken'},
      );

      return await remoteAction(input: MyInput(message: message, count: count));
    } on GenkitException catch (e) {
      throw Exception('Failed to remote action: ${e.message}');
    }
  }

  
  
  
  FlowStreamResponseStreamOutput, StreamOutput> subscribeStreamObjectAction({
    required String idToken,
    required String prompt,
  }) {
    try {
      final remoteAction = defineRemoteActionStreamOutput, StreamOutput>(
        url: '$baseUrl/streamObjects',
        fromResponse: (json) => StreamOutput.fromJson(json),
        fromStreamChunk: (json) => StreamOutput.fromJson(json),
        defaultHeaders: {'Authorization': 'Bearer $idToken'},
      );

      return remoteAction.stream(input: StreamInput(prompt: prompt));
    } on GenkitException catch (e) {
      throw Exception('Failed to remote action: ${e.message}');
    }
  }

  
}

まとめ

本記事では、Dart/Flutter から Genkit フローを快適に呼び出すために開発した Dart client for Genkit を紹介しました。

以前、とある Google 社員の方が Firebase チームの設計思想について話しているのを聞く機会がありました。
その方は「Firebase のインターフェース設計は美しい」と語っており、今回においては、特に Next.js や Angular など、異なるフレームワーク間でも一貫した使い心地を提供するという思想は、私にとって新しい視点でした。
複数プラットフォームに SDK を提供するプロダクトでは、特に意識すべき点だと改めて感じています。

その上で、今回開発に携わったライブラリが、公式クライアントとのインターフェース統一性に関するレビューをいただけたことは、その思想を少しでも体現できたようで、非常に嬉しい経験でした。

昨今、AI がコード生成を助けてくれる場面が増えていますが、最終的な品質を担保するのは、私たち開発者(人間)だと思っています。
だからこそ、人間にとってのコードの可読性やメンテナンス性は、これまで以上に重要になってくると感じています。

このライブラリが、複雑な部分を隠蔽・抽象化し、クリーンなインターフェースを提供することで、その一助となれば幸いです。

参考



Source link

Views: 0

「GiGO、Sallyとの新連携発表!周遊型アトラクション「呪景」を限定開催」


GENDA子会社のGENDA GiGO Entertainmentが、エンターテインメント企業「Sally」との新たな協業を発表しました。この提携の第一弾として、2025年6月21日(土)から22日(日)の日程で、秋葉原のベルサールで「呪景(ジュケイ)」という周遊型イマーシブアトラクションが開催されます。

背景と企業ビジョン

GENDA GiGOは、日本国内外で約470のアミューズメント施設を運営しており、「ASOBIで世界を熱くする」というビジョンのもと、五感を揺さぶる新たな体験を提供しています。一方、Sallyは、体験型エンターテインメント「マーダーミステリー」の普及を目指し、特に中国での成功を経て日本でも人気を集めています。

この提携は、2024年7月の資金調達ラウンドで、GENDA Capitalからの出資を受けたことをきっかけに実現しました。今後は「GiGO」でのリアル店舗体験を共に創出していく予定です。

協業の具体的な内容

提携を通じて、以下のような取り組みが行われます:

  • 店舗活用:GiGOの店舗をSallyの体験型エンタメの舞台として使用。
  • 共同企画:両社の強みを活かした新たなイベントの企画。
  • マーケティング:顧客基盤を活用し、新規ファン層の開拓を目指す。

「呪景(ジュケイ)」の概要

「呪景」は、秋葉原GiGOに存在する魔のクレーンゲームがテーマです。プレイヤーはこのゲームを巡り、さまざまな謎に挑戦する体験をします。体験人数は1人から4人、体験時間は60分から90分です。詳細はこちらをご覧ください。

参加者の反応

イベントに参加した人々からは、「ゲームセンターらしいギミックとストーリーが好きだった」「楽しい体験で、終わった後はたい焼きを食べたくなった」という声が寄せられ、期待の大きさが伺えます。

この協業が、両社にとって新たなエンターテインメントの未来を切り開くことを期待しています。

🧠 編集部より:

この記事では、GENDA子会社のGENDA GiGO EntertainmentとSallyの協業について詳しく述べています。特に注目すべきは、周遊型イマーシブアトラクション「呪景(ジュケイ)」の開催です。このイベントは、2025年6月21日から22日まで秋葉原で行われ、参加者は特別な体験を楽しみました。

補足説明

GENDAとSallyのビジョン

  • GENDAは「ASOBIで世界を熱くする」というビジョンのもと、約470店舗のアミューズメント施設を運営し、リアルエンターテイメントを追求しています。
  • Sallyは、「マーダーミステリー」という体験型エンタメの普及を目指しており、特に中国からの影響を受け、日本でも注目されています。

共同プロジェクトの概要

この協業の第一弾である「呪景(ジュケイ)」は、イマーシブ型コンテンツと店舗ネットワークを組み合わせることで新しいエンターテイメント体験を提供します。

体験内容

参加者は1名から4名で60分から90分の体験が可能で、クレーンゲームを巡る謎を解くというユニークな設定が特徴です。体験者からは、ストーリーやギミックに関する高評価が寄せられています。

豆知識

  • イマーシブアトラクションは、参加者がストーリーの一部となり、実際に体験を通じて物語が進行する仕組みです。最近では、ゲームセンターだけでなく、さまざまな企業が採用しています。
  • マーダーミステリーは、プレイヤーが役割を演じながら進むゲームで、犯人を追い詰める推理や人間関係の駆け引きが楽しめる人気のジャンルです。

このように、GENDAとSallyは新しいエンターテイメントの可能性を模索し続けており、今後の展開が非常に楽しみです!

  • この内容から選定するキーワードは「イマーシブエンターテイメント」です。


イマーシブアトラクション をAmazonで探す

マーダーミステリー をAmazonで探す

クレーンゲーム をAmazonで探す


※以下、出典元
▶ 元記事を読む

Views: 1

「寝不足後の深い眠り、科学が解明!」

📌 ニュース:
なぜ寝不足後に「より深く長く眠るのか」、その科学的メカニズムが解明されました。ジョンズ・ホプキンス大学の研究によれば、睡眠不足が続くと、脳内の特定の神経回路が「寝不足」を記録し、普段より長く深く眠る仕組みがあることが分かりました。睡眠負債は体に影響を与え、認知力や免疫力を低下させるため、注意が必要です。

この研究は、脳が特定の神経回路を用いて、睡眠不足を計測し、次の眠りを深くすることで自己回復を促していることを示しています。私たちの健康のために、睡眠の重要性を再認識しましょう。

  • 以下のポイントをまとめました✨

    1. 脳が記録する「睡眠負債」🧠
      ジョンズ・ホプキンス大学の研究により、脳が睡眠不足を「借金」として記録し、後で長く深く眠る仕組みが発見されました。これにより、体が自動的に睡眠を補うメカニズムが解明されたのです。

    2. 「リユニエンス核」の役割🔍
      睡眠をコントロールする小さな神経細胞集団「リユニエンス核」が、睡眠負債を計測し、十分な睡眠を促すことが明らかになりました。この核が活発になると、自然と「寝だめ」をする深い眠りに入ることができるのです。

    3. 健康維持のための睡眠の重要性💤
      研究は、睡眠が脳や体の健康に不可欠であることを改めて示しています。慢性的な睡眠不足は健康に悪影響を及ぼすため、睡眠を大切にする必要があります。脳には「睡眠の借金」を返済する素晴らしいメカニズムが備わっているのです。


※以下、出典元
▶ 元記事を読む

Views: 2