【テンプレート編】Misskey Playを作ってみよう#1

どうも、出荷前のじゃがいもです
夢はフライドポテトになることです

ということで(???)
今回は初心者向けに
Playの作り方を教えます!


はじめに

Misskeyは知ってますね?(じゃないとこの記事は見ないだろうけど)

MisskeyのPlayという機能では

僕が作った迷路脱出Play

こんな感じにMisskeyユーザーがゲームを作り、投稿することができます
このSNS、面白すぎる…!

趣味で開発をしてる人にとってゲームを公開できるSNSなんてもう夢でしかないですからね
しかもMisskeyの機能と連携して共有とかもできてしまう…!

ベースはMisskey側がほとんど用意してくれていますが、それでも開発にはプログラミングの知識を必要とするものです

でも、そんな人でも気軽に開発を始めてみてほしい…!
そんな想いでこの記事を書いています

テンプレートの準備

大前提としてPCが望ましいです
(テンプレートをいじるだけならギリギリスマホでもいい)

ボタンとかの説明で、UIを英語に設定してますがおそらくこんな名前だろうという訳は付けておきます
(あと、バージョンとかよっても違ったりするかもしれない)

好きな鯖でMisskeyを開いたら、メニューから

このようなボタンでPlayページに飛びます
そしたら
自分のPlay(My Plays)
を選択し
+
と書かれたボタンで新しいPlayを作成します


Note
前に作ったPlayを変更したい場合はMy PlaysからそのPlayを選択し
このPlayを編集する(Edit this Play)
を選択します


そしたら
プリセットを選択(Choose from presets)
というドロップダウンリストから
Omikuji
というプリセット(テンプレート)を選択します

すると、スクリプト(Script)のところに

/// @ 0.19.0
// ユーザーごとに日替わりのおみくじのプリセット

// 選択肢
let choices = [
	"ギガ吉"
	"大吉"
	"吉"
	"中吉"
	"小吉"
	"末吉"
	"凶"
	"大凶"
]

// シードが「PlayID+ユーザーID+今日の日付」である乱数生成器を用意
let random = Math:gen_rng(`{THIS_ID}{USER_ID}{Date:year()}{Date:month()}{Date:day()}`)

// ランダムに選択肢を選ぶ
let chosen = choices[random(0, (choices.len - 1))]

// 結果のテキスト
let result = `今日のあなたの運勢は **{chosen}** です。`

// UIを表示
Ui:render([
	Ui:C:container({
		align: 'center'
		children: [
			Ui:C:mfm({ text: result })
			Ui:C:postFormButton({
				text: "投稿する"
				rounded: true
				primary: true
				form: {
					text: `{result}{Str:lf}{THIS_URL}`
				}
			})
		]
	})
])

このようなコードが出てきます

コードはそのままに、公開範囲(Visibility)を公開(Public)か限定(Private)にして保存(Save)します


Note
公開範囲をPublicにすると誰でも見れます
Privateにするとリンクを知っている人だけがアクセスできます
(要するに、プロフィールのPlay欄とかPlayの人気Play欄からのアクセスとかがなくなる)


下に行くとプレビュー(Show)があるので見てみます(最後に保存されたPlayが表示されます)

実行結果

このプリセットは、このように
大吉,中吉,小吉…
といった決まった単語をランダムに選び
今日のあなたの運勢は[選んだ単語]です。
と表示する機能と、それを投稿するボタンがあります

コードを読んでみる

このPlayがどのような仕組みで動いているのかを見てみます
今回は最初なので、細かい仕組みについては触れずにざっといきます

まず

/// @ 0.19.0
// ユーザーごとに日替わりのおみくじのプリセット

このように
//
から始まる行は処理に影響しないので好きに書き換えたりしても問題ないですし、新しく追加してもいいです


Note
この機能のことをコメントと言います
コメントはコードを読む助けになるので、できるだけコメントで処理内容を書いておくといいです(特に初心者のうちは、といっても初心者はコメントを書かないのですが…)
このコメントは行の途中に挟むと、そこから行末までを無視します
なので、実際には//から行末までを無視するのがコメントです


その下を見てみると

// 選択肢
let choices = [
	"ギガ吉"
	"大吉"
	"吉"
	"中吉"
	"小吉"
	"末吉"
	"凶"
	"大凶"
]

とあります、これがランダムで選ばれる単語の列になります
その列に対して、choicesという名前を付けて保存しています

// シードが「PlayID+ユーザーID+今日の日付」である乱数生成器を用意
let random = Math:gen_rng(`{THIS_ID}{USER_ID}{Date:year()}{Date:month()}{Date:day()}`)

// ランダムに選択肢を選ぶ
let chosen = choices[random(0, (choices.len - 1))]

ここはまだ飛ばしておきます
ざっくり言うと、ランダムな数を選んでくれるrandomという機能を最初に作っています
次に、上で見たchoicesにrandomの機能を使って1つの単語を選びます、それによって選ばれた単語にはchosenという名前を付けています

// 結果のテキスト
let result = `今日のあなたの運勢は **{chosen}** です。`

ここで、今日のあなたの運勢は~という文章に、上で選んだchosenを埋め込んで、できた文章に対してresultという名前を付けています
この文章は、画面に表示するときに使い、投稿する部分にも再利用します

// UIを表示
Ui:render([
	Ui:C:container({
		align: 'center'
		children: [
			Ui:C:mfm({ text: result })
			Ui:C:postFormButton({
				text: "投稿する"
				rounded: true
				primary: true
				form: {
					text: `{result}{Str:lf}{THIS_URL}`
				}
			})
		]
	})
])

ここで画面に表示する処理を行います
長くなるので全部は話しませんが

Ui:C:mfm({ text: result })

の部分で、resultと名付けた文章をMFMとして画面に表示しています


Note
MFMはMisskeyの機能で、プレーンなテキスト(日本語や、😋や🚙のような標準的な文字列)に対し、Misskeyが定義した様式での独自の表示ができます
例えば、文章中にカスタム絵文字を書いた場合
プレーンなテキストでは
:omae:
だとしても、MFMとして読むとそこがカスタム絵文字に切り替わります
$[spin ~]
と言った制御用の構文についても同じです
このように、Misskeyの機能で読んだ結果、要するにノートで表示されるような文章のことをMFMと言います


Ui:C:postFormButton({
	text: "投稿する"
	rounded: true
	primary: true
	form: {
		text: `{result}{Str:lf}{THIS_URL}`
	}
})

の部分では投稿ボタンを表示しています、特にこの中の

form: {
	text: `{result}{Str:lf}{THIS_URL}`
}

の部分では投稿フォーム(form)の投稿文(text)として
resultと名付けられた文章
改行
このPlayのリンク
の3つを並べています

コードを書き変えてみる

ここから、読んだ結果も踏まえてオリジナルの要素を追加していきます
今回変更する点は
・ランダムに選ばれる単語を変更する
・投稿文を変える
の2つを試してみます

ランダムに選ばれる単語を変更する

選ばれる単語は

// 選択肢
let choices = [
	"ギガ吉"
	"大吉"
	"吉"
	"中吉"
	"小吉"
	"末吉"
	"凶"
	"大凶"
]

の部分に並べてありましたね
この部分を、以下の例を参考に好きな文字に変えてみてください

// 選択肢
let choices = [
	"1時"
	"2時"
	"3時"
	"4時"
	"5時"
	"6時"
	"7時"
	"8時"
	"9時"
	"10時"
	"11時"
	"12時"
]

ここからは解説です、知らなくてもプリセットはいじれますが、今後の記事の理解が深まったりバグの修正が出来たりします
初めて見る概念だと馴染むのに時間がかかるかもしれません(それはもう何度も触れるしかないのですが…)

[ ]
で囲まれた部分をリストと呼びます
買い物リストとかのリストです
リストで覚えておいて欲しいのは
いくつかの要素をまとめる
順番に意味がある
ということです
いくつかの要素とは、今回で言えば"ギガ吉"とか"大吉"みたいなものです
これは数字だったり、リストだったり色々ありますがすべて要素と呼びます
順番に意味があるとは、"ギガ吉"は1番目、"大吉"は2番目…といったことも保存しているということです、順番を保存することによって、このリストの何番目の要素は何か…といったような取り出し方ができます

もう1つ
" "
で囲まれた部分は文字列と言います
要するに文章のことです
わざわざ"(ダブルクォーテーション)を書く理由は、コードと区別するためです
例えば、choicesという文章を文字列として扱いたい場合、これがchoicesと名前を付けられたリストなのか、文字列なのか分かりません、なので"choices"と書いてこれが文字列であることを明記するわけです
囲むものは"でなくても、'(シングルクオーテーション)で囲んでも同じ意味になります、どちらかで統一した方が統一感が出ますが場合によっては混在する方が楽なこともあります("で始めたらその末尾には"、'で始めたらその末尾には'を置くといったことは守らなければいけません)

let choices =
というところは、この先に書くもの(今回はリスト)に対してchoicesという名前を付けるという意味です
例えば
let good="大吉"
とすれば、"大吉"という文字列に対してgoodという名前を付けたことになります
このchoicesやgoodといった名前のことを変数と言います
名前を付ける意味は、それを後で使うためです、せっかくリストを作ったのにそれを呼ぶことができなければ使えませんから
変数の付け方としては
半角英数字か_(アンダーバー)のみを使う
数字以外の文字から始める
・重複してはいけない
必要があります
例えば、goodやchoicesといった名前は大丈夫ですし、level1やsplited_sentenceといった命名もできます
しかし、1levelという名前にはできません
変数は、それが何を指しているかを考えて付けるようにしましょう(初心者はたまにaとかbみたいな変数名を付けるが、だいぶ読みづらくなる)


Note
文字列は、文字のリストと考えることもできます(言語によっては本当にそのように実装していることもあります)
"あいうえお"という文字列があれば、'あ'という文字が1番目、'い'という文字が2番目…といったリストとして解釈することができます
C言語を学ぶとそれがよく分かると思います


投稿文を変える

次に投稿文を変えます
変えるのはこの部分です

// 結果のテキスト
let result = `今日のあなたの運勢は **{chosen}** です。`

これを、こんな風に変えます

// 結果のテキスト
let result = `**午後{chosen}** をお知らせします。`

解説に入ります

` `
で囲まれた部分も"や'と同じく文字列になります
違いは、変数などを挿入できるということです
この文字列の中にある
{ }
で囲まれた部分は、中身を文字列として埋め込みます
今回はchosenと書いているので、この変数が指す文字列が入ることになります(chosenはchoicesリストからランダムに選ばれた単語に対する変数です)


Note
文字列は",',`で囲むことで表せますが、これらの記号を文字として扱いたい場合にはどうしたらいいでしょう?
これはエスケープという処理を行います
今回は
"を\"
'を\'
`を\`
とすることによってこれらを文字として扱えるようにします
例えば
"お前"

お前
を指しますが
"\"お前\""
と書けば
"お前"
を指すことになります
この場合は
'"お前"'や`"お前"`
のように、別の囲いで囲むことでも対応できます(一番外側が優先されます)
バックスラッシュ(\)自身のエスケープは
\\
です

実行

ここまでのコードをまとめると

/// @ 0.19.0
// ユーザーごとに日替わりのおみくじのプリセット

// 選択肢
let choices = [
	"1時"
	"2時"
	"3時"
	"4時"
	"5時"
	"6時"
	"7時"
	"8時"
	"9時"
	"10時"
	"11時"
	"12時"
]

// シードが「PlayID+ユーザーID+今日の日付」である乱数生成器を用意
let random = Math:gen_rng(`{THIS_ID}{USER_ID}{Date:year()}{Date:month()}{Date:day()}`)

// ランダムに選択肢を選ぶ
let chosen = choices[random(0, (choices.len - 1))]

// 結果のテキスト
let result = `**午後{chosen}** をお知らせします。`

// UIを表示
Ui:render([
	Ui:C:container({
		align: 'center'
		children: [
			Ui:C:mfm({ text: result })
			Ui:C:postFormButton({
				text: "投稿する"
				rounded: true
				primary: true
				form: {
					text: `{result}{Str:lf}{THIS_URL}`
				}
			})
		]
	})
])

このようになります
この状態で、もう一度保存をしてShowを押すと実行できます

書き換え後の実行結果

最後に

こんな感じで、実際にPlayを作成することを通してPlayの作り方を書いていこうと思います

では、また次の記事で

この記事が気に入ったらサポートをしてみませんか?