「牛の舌って薄いんですね」

蒼樹うめ『ひだまりスケッチ』第 6 巻「一頭から一枚」より

MinecraftForge 1.16 で CocoaInput を使う

Mac で日本語入力できるようにする MinecraftForge Mod の『CocoaInput』ですが、2021 年 1 月 13 日時点での最新版 3.2.3 は MinecraftForge 1.16 に対応していません。

他の有志によって 1.16 対応のパッチが出されているのですが、本記事の執筆時点では、取り込まれずに放置されています。

github.com

このパッチを当ててビルドした CocoaInput を Google ドライブに上げておいたので、以下からダウンロードしてご利用ください。

[2021-03-09 追記]

修正版がリリースされたので、こちらでの公開を終了しました。以下から公式のビルドをダウンロードしてください。

CocoaInput - Mods - Minecraft - CurseForge

[/追記]


以下、自分でビルドしたい方のためにビルド手順を残しておきます。

1. ターミナル.app を起動します。

起動の仕方がわからない人はググってください。次の手順からターミナルで実行するコマンドを記載していきますが、行頭の $ を入力する必要はありません。

2. JDK をインストールする。

JDKJava Development Kit)がお使いの Mac にインストールされていない場合、インストールする必要があります。

ターミナルで次のコマンドを実行してください。

$ java -version

「No Java runtime present, requesting install.」と表示された場合、JDK がインストールされていません。以下のサイトなどを参考にして、JDK をインストールしてください。

maysatsuki.com

3. ソースコードを取得して、ビルドします。

一行ずつ実行してください。

$ cd $TMPDIR
$ git clone https://github.com/lukuon/CocoaInput.git
$ cd CocoaInput
$ git checkout 1.16.3
$ ./gradlew build

ビルドが完了するのを待ちます。環境によりますが、数分かかります。

4. ビルドしてできた Mod を MinecraftForge の mods ディレクトリに移動します。

MinecraftForge をデフォルトのディレクトリにインストールしている場合は、次のコマンドで移動できます。

$ mv build/libs/CocoaInput-\[1.16.3\]-3.3.0.jar ~/Library/Application\ Support/minecraft/mods/

または、次のコマンドで Finder が開くので、CocoaInput-[1.16.3]-3.3.0.jar をドラッグ&ドロップで移動させてください。

$ open build/libs

5. MinecraftForge を起動する。

問題なく動作するか確認してください。

6. (任意)~/.gradle を削除する。

./gradlew build を実行したときに Gradle がキャッシュなどを残していきます。そのままにしておいても問題ありませんが、気持ち悪い場合は次のコマンドで削除できます。

$ rm -rf ~/.gradle

なお、$TMPDIR にダウンロードしたソースコードは、3 日後に自動的に削除されるので、そのままで問題ありません。


以上です。わからないことがありましたら、コメントか、Twitter または Mastodon で質問してください。

『アイマスしりとり』を作った

この記事は、アイドルマスター Advent Calendar 2020 の 24 日目の記事です。

PHP 関数名しりとりに着想を得て、アイドルマスターのアイドルの名前でもしりとりできないかと思い、『アイマスしりとり』なるものを作ってみました。

遊び方

アイドルマスターのアイドルの名前(漢字でもひらがなでも可)で、Bot としりとりで対戦していただきます。

imas-siritori.pikopikopla.net

突貫で作ったので作りが荒いところもありますが、大目に見てください・・・。ソースコードは以下で公開しています。

github.com

アイドルのデータは、おなじみ im@sparql から取得しています。アイドルの名前の読みを取得するのにちょっと苦労したので、実際に使用した SPARQL クエリをサンプルとして載せておきます。

やり残したこと

リファクタリング

突貫で作ったのでソースコードが汚いです・・・。1 つの React コンポーネントにロジックが集中していたりして、作り直したい・・・。

しりとりルールの修正

「ー」で終わったときはその前の文字から始めるとか、濁音・半濁音は無視するとか、しりとりには特別ルールがありますが一切実装できていません。このあたり調整したいです。

即終了対策

必ず Bot が勝ってしまうアイドルの名前を一発目から出されると萎えてしまうので、出さないように調整したいです。

ブランドによる絞り込み

今のところ、すべてのブランドからアイドルを出していますが、ブランドごとに絞り込める機能を考えています。

PWA 化

スマホアプリとして追加して、オフラインでも遊びたいですよね。いつでもどこでも、アイマスですよ、アイマス

宣伝

アイドルマスター Advent Calendar 2020 では、執筆者を募集中です。明日で終わりにもかかわらず、空席がたくさん出ています。ぜひご参加ください!

adventar.org

☆ピコピコプラネット☆ SPACE を支える技術

この記事は、Linked Open Data Advent Calendar 2020 の 21 日目の記事です。

昨日は、私の開発する『☆ピコピコプラネット☆ SPACE』(以下、ピコプラ SPACE)が LOD チャレンジ 2020 で受賞した話を書きましたが、今日は、そのピコプラ SPACE がどのような技術でできているのか、紹介したいと思います。ソースコードは以下で公開しています。

github.com

フロントエンド

Next.js

最近話題の React 製 JavaScript フレームワークです。SSR(Server Side Rendering)できるフレームワークとして登場しましたが、最近の機能追加によって SSG(Static Site Generation)も可能になったり、ISR(Incremantal Static Regeneration)という新しいページ生成方法が導入されたり、非常に期待のできるフレームワークとなってきております。これらのページ生成方法を、ページごとに簡単に選択できるのがとてもメリットだと感じています。ピコプラ SPACE では、トップページなど静的なページでは SSG + Client Side Data fetching(つまり Ajax)、クエリページでは ISR などと使い分けています。

Next.js を採用した理由としては、Twitter の OGP 画像表示に対応させるため SSR が必須だったこと、ファイルシステムベースのルーティングが便利だったこと、React と TypeScript の相性がよかったこと、が挙げられます。実際に使ってみると、Zero-config を謳っているだけあって設定の必要が少なく、非常にシンプルでわかりやすいと感じました。現状、開発元の Vercel にデプロイするのが最善で、ロックインの懸念はありますが、今後もぜひ採用していきたいフレームワークです。

nextjs.org

Semantic UI

CSS フレームワークというと Bootstrap などが思い浮かびますが、Semantic UI も人気のあるフレームワークです。Semantic UI の React コンポーネントを提供する Semantic UI React と一緒に使用しています。エンジニアの作るサイトというと、どうしても見た目が似たようになってしまう傾向がありますが、そんなときに試してみてはいかがでしょうか。

semantic-ui.com

SWR

React Hooks で記述できる Client Side Data fetching ライブラリです。Next.js 開発元の Vercel が開発しています。複雑になりがちな React の Data fetching を簡単に記述することができ、stale-while-revalidate というキャッシュ戦略により UX を高めてくれます。

swr.vercel.app

CodeMirror

ブラウザ上で動作するテキストエディタです。SPARQL のシンタックスハイライトが入っているので、これを使用しました。React との橋渡しのため react-codemirror2 を使用しています。

codemirror.net

Comunica SPARQL RDFJS Init Actor

なんだこれは・・・。Comunica という TypeScript で実装された RDF フレームワークがあるんですが、それを構成するライブラリ群のうちの SPARQL 実行に関するライブラリになります。ピコプラ SPACE のどこで使っているかというと、SPARQL エンドポイントの部分です。実は仮実装のピコプラ SPACE の SPARQL エンドポイントは、Apache Jena や Virtuoso などの RDF データベースを用意しているわけではなく、Next.js の SSR で動いているのです・・・。投稿されたクエリの数がまだまだ少ないので、これで十分だろうと考えています。N3.js と一緒に使用しています。

comunica.dev

バックエンド

Firebase Authentication

みんな大好き Firebase の認証システムです。とても手軽に導入でき、何より無料で使えるのがすごいですね。ピコプラ SPACE では、Google 連携、Facebook 連携、Twitter 連携、GitHub 連携、メールアドレス登録を有効にしていますが、他にも様々なアカウント連携が可能です。これらを自ら実装することなく、安全にユーザー認証を扱うことができます。

Firebase Cloud Firestore

みんな大好き Firebase の NoSQL クラウドデータベースです。スケーラビリティと引き換えに多くの制限があるので、評価は分かれるところです。特に Firestore では簡単な JOIN もできないので、RDB 脳ではスキーマ設計にかなり悩まされることになるでしょう。ただ、何と言ってもやはり無料枠がかなり大きいのが魅力的です。

Cloudinary

画像・動画管理のクラウドサービスです。このサービスの特徴は、画像や動画をパラメータをつけてリクエストすることで、そのパラメータに従って画像や動画を加工して返してくれるところです。ピコプラ SPACE では、Twitter の OGP 画像生成に利用しています。類似サービスは他にもありますが、無料枠が大きいところが魅力的です。画像加工において、デフォルトでは日本語フォントには対応していませんが、フォントをアップロードすることで使用することができます。ピコプラ SPACE では Noto Sans JP をフォント指定していますが、絵文字が表示されないのが残念です。ばんじゅん🍓さん、ごめんなさい。

まとめ

あまり LOD と関係ない記事になってしまいました。SPARQL 共有サービス『☆ピコピコプラネット☆ SPACE』は、このような技術を組み合わせてできております。お気づきかもしれませんが、かなりクラウドサービスの無料枠に頼ったところが大きく、現状コストが発生しているのは毎年のドメイン代くらいです。ドメインの更新を忘れたり、使用しているサービスの改定があったりしないかぎり、ピコプラ SPACE が終了することはないでしょう。みなさまの投稿をお待ちしております。

space.pikopikopla.net

宣伝

Linked Open Data Advent Calendar 2020 では、執筆者を募集中です。枠はまだまだたくさんありますので、ぜひご参加ください。

adventar.org

LOD チャレンジ 2020 参加レポート

この記事は、Linked Open Data Advent Calendar 2020 の 20 日目の記事です。

参加の経緯

Twitter でお知らせしましたとおり、Linked Open Data チャレンジ Japan 2020(LOD チャレンジ 2020)において、私の開発する『☆ピコピコプラネット☆ SPACE』が、「LODコミュニティ賞」と「楽しくSPARQL賞(B Inc.)」の 2 つの賞を受賞しました。

本日(12 月 20 日)LOD チャレンジ 2020 オンライン授賞式シンポジウムが開催され、受賞作品の発表を行いました。

LOD チャレンジについて

LOD チャレンジは、幅広い分野におけるオープンなデータづくりとデータを活用した取り組を表彰するコンテストとして、2011年に日本で初めて開催されました(LOD チャレンジ 2020 開催趣旨より引用)。今年で 9 回目の開催になります。

私がコントリビュートしているプロジェクトのなかでは、croMisa さんの im@sparql が 2018 年にデータセット部門で優秀賞を、みかみんさんの rdflint が 2019 年に基盤技術部門で優秀賞を受賞しています。私が主導して開発しているプロジェクトとしては、今回初めての応募でした。

例年、LOD チャレンジ授賞式シンポジウムは、東京都や神奈川県で開催されてきましたが、今年は昨今の事情により、オンラインで開催されることになりました。京都府在住の私としては、遠征費がかからず参加することができラッキーでした。参加者が製作物を直接触ってみることができるなど、オンラインならではのメリットもありました。

受賞作品について

受賞作品の『☆ピコピコプラネット☆ SPACE』についてですが、SPARQL クエリの共有サイトとなっております。ユーザーが投稿した SPARQL クエリを閲覧したり、実行したりすることができます。詳しくは、授賞式で使用した以下の発表資料をご覧ください。

docs.google.com

SPARQL クエリの共有に便利な Web サービスとなっておりますので、ぜひご活用いただければと思います。ご要望・不具合報告などもお気軽にお問い合わせください。

space.pikopikopla.net

みなさんもぜひご参加を

LOD チャレンジは、きっと来年も開催されると思いますので、興味がある方はぜひご参加ください。LOD を知らなかった方も、この機会にぜひ興味を持っていただければ幸いです。

2020.lodc.jp

宣伝

Linked Open Data Advent Calendar 2020 では、執筆者を募集中です。枠はまだまだたくさんありますので、ぜひご参加ください。

adventar.org

『☆ピコピコプラネット☆』を使ってみる

この記事は、アイドルマスター Advent Calendar 2019 の 3 日目の記事です。

3 日目が空席でしたので、昨日の記事に引き続き、『☆ピコピコプラネット☆』について書かせていただきたいと思います。

アルバム情報の取得

『☆ピコピコプラネット☆』で現状最も情報が多いのがアルバム情報です。ランティスのミリオンライブのページに掲載されているものから、ソロコレクション、コミックの特典まで網羅しています。

そのアルバム情報の SPARQL での引き方について見ていきましょう。

アルバムと曲の関係

まず『THE IDOLM@STER LIVE THE@TER PERFORMANCE 01』(LTP01)のリソースの記述を見てみましょう。

<LTP_01> a :MusicAlbum ;
    :name "THE IDOLM@STER LIVE THE@TER PERFORMANCE 01" ;
    :numTracks 4 ;
    :track [
        a :MusicRecording ;
        :recordingOf <Thank_You> ;
        :byArtist <765_MILLIONSTARS> ;
        :position 1
    ] , [
        a :MusicRecording ;
        :recordingOf <Thank_You> ;
        :byArtist <765PRO_ALLSTARS> ;
        :position 2
    ] , [
        a :MusicRecording ;
        :recordingOf <Thank_You> ;
        :byArtist <765THEATER_ALLSTARS> ;
        :position 3
    ] ;
    :albumRelease [
        a :MusicRelease ;
        :url <https://www.lantis.jp/imas/release_LACM-14080.html> ;
        :image <https://www.lantis.jp/imas/img/release_imgs__0011s_0012_LTP01_H1.png> ;
        :catalogNumber "LACM-14080" ;
        :datePublished "2013-04-24"^^xsd:date
    ] ;
    :isPartOf <LTP_Series> .

『☆ピコピコプラネット☆』では、schema.org をベースとして記述しているため、http://schema.org/プレフィックス: をあてています(普通は schema: が使われることが多いです)。こうすることで記述量を減らせるというメリットがあります。

:track は複数の :MusicRecording を持ちます。その :MusicRecording:recordingOf:MusicComposition(曲)を、:byArtist:MusicGroup(ユニット)を持ちます。

:track に直接曲名やユニット名を記述しないのは、アルバムと曲は多対多の関係にあるからです。アルバムは複数の曲を収録していますし、曲は複数のアルバムに収録される可能性があります(アーティストが違う場合もある)。

f:id:foooomio:20191208213855p:plain

LTP01 に収録されている曲とアーティストを取得するクエリは以下のようになるでしょう。

BASE <https://mltd.pikopikopla.net/resource/>
PREFIX : <http://schema.org/>

SELECT ?song ?artist
WHERE {
  <LTP_01> :track [
    :recordingOf/:name ?song ;
    :byArtist/:name ?artist
  ] .
}

:recordingOf/:name ?song:recordingOf [ :name ?song ] と記述するのと同等です。

ユニット名のないユニット

:byArtist が取りうる値には現状 3 パターンあります。

  • ユニット名ありの :MusicGroup
  • ユニット名なしの :MusicGroup(空白ノード)
  • アイドル mltd:Idol

例えば、LTP02 は以下のようになっています。

<LTP_02> a :MusicAlbum ;
    :name "THE IDOLM@STER LIVE THE@TER PERFORMANCE 02" ;
    :numTracks 13 ;
    :track [
        a :MusicRecording ;
        :recordingOf <キラメキ進行形> ;
        :byArtist <天海春香> ;
        :position 2
    ] , [
        a :MusicRecording ;
        :recordingOf <透明なプロローグ> ;
        :byArtist <七尾百合子> ;
        :position 4
    ] , [
        a :MusicRecording ;
        :recordingOf <トキメキの音符になって> ;
        :byArtist <箱崎星梨花> ;
        :position 6
    ] , [
        a :MusicRecording ;
        :recordingOf <Maria_Trap> ;
        :byArtist <天空橋朋花> ;
        :position 8
    ] , [
        a :MusicRecording ;
        :recordingOf <Precious_Grain> ;
        :byArtist <最上静香> ;
        :position 10
    ] , [
        a :MusicRecording ;
        :recordingOf <Legend_Girls> ;
        :byArtist [
            a :MusicGroup ;
            :member
                <天海春香> ,
                <天空橋朋花> ,
                <七尾百合子> ,
                <箱崎星梨花> ,
                <最上静香>
        ] ;
        :position 12
    ] ;
    :albumRelease [
        a :MusicRelease ;
        :url <https://www.lantis.jp/imas/release_LACA-15300.html> ;
        :image <https://www.lantis.jp/imas/img/release_imgs__0011s_0011_LTP02_H1.png> ;
        :catalogNumber "LACA-15300" ;
        :datePublished "2013-05-29"^^xsd:date
    ] ;
    :isPartOf <LTP_Series> .

『Legend Girls』を歌唱しているユニットにはユニット名がつけられていないため、:name を持たない :MusicGroup の空白ノードを記述しています。

したがって、LTP02 に収録されている曲名と歌っているアイドルを取得するクエリはこのようになります。

BASE <https://mltd.pikopikopla.net/resource/>
PREFIX : <http://schema.org/>

SELECT ?song (GROUP_CONCAT(?artist) AS ?members)
WHERE {
  <LTP_02> :track [
    :recordingOf/:name ?song ;
    :byArtist/:member?/:name ?artist
  ] .
}
GROUP BY ?song

ちょっと複雑になりましたね・・・ちなみにこれを <LTP_01> でやるとうまくいかないです(あかんやん)。

OPTIONALIF を組み合わせれば、いい感じに取得することは可能だと思います。多分・・・ちょっと思いつかなかったです。

可能性は無限大?

締まりのない終わり方でしたが、使い方次第でいろいろなことができると思います。SPARQL クエリの書き方が難しいですが・・・

みなさんもぜひ触ってみてください。

mltd.pikopikopla.net

宣伝です!

今週末の 12 月 7 日(土)、アイマスハッカソン 2019 が関東と関西で同時開催されます。参加者はまだ受付中ですので、ご興味ありましたら是非ご参加ください!