tag:crieit.net,2005:https://crieit.net/tags/WorldType/feed 「WorldType」の記事 - Crieit Crieitでタグ「WorldType」に投稿された最近の記事 2019-01-18T10:46:42+09:00 https://crieit.net/tags/WorldType/feed tag:crieit.net,2005:PublicArticle/14710 2019-01-04T07:59:07+09:00 2019-01-18T10:46:42+09:00 https://crieit.net/posts/2019 2019年の抱負:「釣りタイ駆動開発」 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>あけましておめでとうございます。@iotasです。<br /> 普段は個人開発で、<a target="_blank" rel="nofollow noopener" href="https://www.world-type.com">WorldType</a>という物語創作のためのWebサービスを運営しています。</p> <h2 id="今年のテーマ"><a href="#%E4%BB%8A%E5%B9%B4%E3%81%AE%E3%83%86%E3%83%BC%E3%83%9E">今年のテーマ</a></h2> <p>今年は釣りタイ駆動開発にチャレンジします。</p> <h3 id="釣りタイ駆動開発とは"><a href="#%E9%87%A3%E3%82%8A%E3%82%BF%E3%82%A4%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%81%A8%E3%81%AF">釣りタイ駆動開発とは</a></h3> <p>釣りタイ駆動開発をまだご存知でない方のために説明すると、釣りタイ駆動開発とは私がついさっき思いついた手法で、「未来に作られているであろう記事のタイトル(釣りタイトル)」を妄想して、それに現実を合わせていく開発スタイルです。</p> <p>具体例を出した方がわかりやすいかもしれません。</p> <p>例えば、私と皆さんがあるアイドルグループのメンバーをやってると仮定しましょう。数年後に大成功した自分達について書かれているであろう雑誌の記事のタイトルを妄想します。この際、実現性とか現実は無視します。</p> <p>こんなタイトルが思い浮かびました。</p> <pre><code>「秋元康も絶讃! ○○のステージはなぜそこまで人を魅了するのか」 </code></pre> <p>このタイトルが私達のゴールになります。<br /> 次にこのタイトルの記事の中身を考えていきます。</p> <p>未来の私達のことが書かれた記事には一体何が書かれているのか。<br /> なんでこんなタイトルが付けられているのか、ゆっくり考えていきましょう。</p> <h3 id="アウトラインを考える"><a href="#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%92%E8%80%83%E3%81%88%E3%82%8B">アウトラインを考える</a></h3> <p>わざわざ秋元康さんが絶讃するぐらいだから、他のグループと比べて何か特に秀でた点があるに違いありません。<br /> - ステージの演出が他と比べてすごい?<br /> - メンバーの素の表情が見られる?<br /> - 会場の一体感がハンパない?</p> <p>記事に登場する人物についても考えてみましょう。<br /> まずプロデューサーが出てくるのは間違いないでしょう。彼or彼女が話していそうな内容も妄想します。</p> <pre><code>プロデューサー「いえ、実はそういう効果を狙ってたわけじゃないんです(笑)。 リーダーが『こんなことやったら楽しいんじゃないか』って言い出して。結果的になくてはならない文化になったのは偶然でした」 </code></pre> <p>たぶん経済評論家だかアイドル評論家みたいな人が出てきます。</p> <pre><code>評論家「私も一度ライブに行ってみたんですが、実は現場ではいまいちピンとこなかったんです。『なんでこんなに熱狂してるんだろう』って。でも家に帰ってお風呂に入っていると『ああ、あれは楽しかったな』ってどんどんステージのことが脳裏に浮かび始めて。後でたまたま心理学者の人にその話をしてみたんですが、あのステージにはそういう仕掛けが随所に施されているらしくて……」 </code></pre> <p>妄想しているうちに「今の私達」が辿っていくべき道筋のヒントが見えてきます。<br /> - 何か特別な文化を創る<br /> - 後で思い返せるような心理学的な効果を狙った演出をする</p> <p>じゃあ特別な文化を作るには? <br /> → 他の人はどんなライブをしてるのか調べないといけない</p> <p>心理学的な効果を狙うには?<br /> → 心理学について学ばないといけない(あるいは専門家にお願いしないといけない)</p> <p>こんな感じで「未来の記事」をどんどん具体化していくことによって、「今やるべきこと」が明らかになるわけです。</p> <h3 id="この手法の何がいいのか"><a href="#%E3%81%93%E3%81%AE%E6%89%8B%E6%B3%95%E3%81%AE%E4%BD%95%E3%81%8C%E3%81%84%E3%81%84%E3%81%AE%E3%81%8B">この手法の何がいいのか</a></h3> <p>みんながこれを「妄想だ」と認識した上でアイデアを考えられることです。<br /> どうせ妄想なので好き勝手に言えます。</p> <p>更に「書かれていそう感」にこだわることによって、現実から大きく乖離することもありません。</p> <p>妄想を楽しみながら、目指すゴールに至るための道筋を表すことができます。</p> <p>なお冒頭に書いたとおり、釣りタイ駆動開発はさっき思いついたのでエビ(証拠)はありません。</p> <h2 id="今年のWorldTypeの釣りタイ"><a href="#%E4%BB%8A%E5%B9%B4%E3%81%AEWorldType%E3%81%AE%E9%87%A3%E3%82%8A%E3%82%BF%E3%82%A4">今年のWorldTypeの釣りタイ</a></h2> <p>「なぜWorldTypeを使っているユーザーはエタりが少ないのか」<br /> で行きたいと思います。<br /> (エタる:作品が未完のまま途中で止まってしまうこと。「エターナる」)</p> <p>作品を幸せに完結できるように、作者さんをフォローしていく方法を考えて開発していきたいと思います。</p> <p>2019年:「なぜWorldTypeを使っているユーザーにエタりが少ないのか」<br /> 2020年:「なぜWorldTypeは創作界の火薬庫と呼ばれるのか」<br /> 2021年:「WorldTypeが海外に進出したその理由」</p> <h2 id="昨年の御礼"><a href="#%E6%98%A8%E5%B9%B4%E3%81%AE%E5%BE%A1%E7%A4%BC">昨年の御礼</a></h2> <p>2018年はWorldTypeを愛用してくださるユーザーの皆様を始め、多くの方々に大変お世話になりました。</p> <p>とりわけ、このCrieitを運営されているdala様など開発コミュニティの皆様と多くのコミュニケーションを取らせていただき、勉強になるわ楽しいわ心の支えになるわで大変なことでした。</p> <p>ありがとうございます。<br /> 本年もよろしくお願いいたします。</p> iotas𓆡創作支援アプリ運営中𓅬 tag:crieit.net,2005:PublicArticle/14638 2018-12-10T00:23:32+09:00 2018-12-10T23:47:14+09:00 https://crieit.net/posts/WorldType 創作支援ツール「WorldType」に使われている技術 <h1 id="創作支援ツール「WorldType」に使われている技術"><a href="#%E5%89%B5%E4%BD%9C%E6%94%AF%E6%8F%B4%E3%83%84%E3%83%BC%E3%83%AB%E3%80%8CWorldType%E3%80%8D%E3%81%AB%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E6%8A%80%E8%A1%93">創作支援ツール「WorldType」に使われている技術</a></h1> <p>こちらはCrieitの<a href="https://crieit.net/advent-calendars/2018/technology">個人開発サービスに用いられている技術 Advent Calendar 2018</a>の10日目の記事です。</p> <p>昨日は<a href="https://crieit.net/users/8398a7">8398a7</a>さんの<a href="https://crieit.net/posts/SP-12">「SP☆12参考表(地力表)支援サイト を支える技術」</a>でした。</p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://twitter.com/triaez1">@iotas</a>です。物語を作る人向けの創作支援ツール「<a target="_blank" rel="nofollow noopener" href="https://www.world-type.com">WorldType</a>」というものを作っています。<br /> <a href="https://crieit.now.sh/upload_images/9d3d1224aa03a2016d13c93ebb9a70de5c0d12ab68d23.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d3d1224aa03a2016d13c93ebb9a70de5c0d12ab68d23.jpg?mw=700" alt="eyecatch.jpg" /></a></p> <p>今回はアドベントカレンダーということで、このサービスの「中の技術」の紹介となります。</p> <p>これ、結構ごった煮なんですよね。</p> <p>面白いと思うか、ごちゃごちゃと見るか……。多分面白いって思ってもらえるんじゃないかな。</p> <p>それでは見てみましょう。</p> <h2 id="フロントエンド"><a href="#%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89">フロントエンド</a></h2> <p>JavaScript部分はまだ<a target="_blank" rel="nofollow noopener" href="https://jquery.com/">jQuery</a>が多いですね。最近は<a target="_blank" rel="nofollow noopener" href="https://jp.vuejs.org/index.html">Vue.js</a>を使い始めています。</p> <p>更に後述しますがTypeScriptで書いている部分もあります。</p> <p><a target="_blank" rel="nofollow noopener" href="https://materializecss.com/">Materialize</a>というCSSフレームワークを使ってます。Vueの部分は<a target="_blank" rel="nofollow noopener" href="https://element.eleme.io/#/en-US">Element</a>というUIライブラリも使ってます。</p> <h2 id="バックエンド"><a href="#%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89">バックエンド</a></h2> <p>PythonのDjangoフレームワークを使ってます。</p> <p>API部分は、Django REST frameworkを使っています。</p> <h2 id="PaaS"><a href="#PaaS">PaaS</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://jp.heroku.com/">Heroku</a>です。</p> <h2 id="メール配信"><a href="#%E3%83%A1%E3%83%BC%E3%83%AB%E9%85%8D%E4%BF%A1">メール配信</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://www.mailgun.com/">Mailgun</a>を使ってます。</p> <h2 id="エラートラッキング"><a href="#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%88%E3%83%A9%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0">エラートラッキング</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://sentry.io/welcome/">Sentry</a>です。</p> <h2 id="実際に見ていく"><a href="#%E5%AE%9F%E9%9A%9B%E3%81%AB%E8%A6%8B%E3%81%A6%E3%81%84%E3%81%8F">実際に見ていく</a></h2> <p>さあ、ここからはごった煮部分を一個一個追っていきましょう。</p> <h3 id="ログインした後のダッシュボード"><a href="#%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%97%E3%81%9F%E5%BE%8C%E3%81%AE%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E3%83%9C%E3%83%BC%E3%83%89">ログインした後のダッシュボード</a></h3> <p><a href="https://crieit.now.sh/upload_images/ff995edd3991e2fe53b38dff1693a4a85c067ca893466.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ff995edd3991e2fe53b38dff1693a4a85c067ca893466.jpg?mw=700" alt="dashboard.jpg" /></a></p> <p>わかりやすくMaterialデザインっぽいですね。</p> <p>CardやボタンはMaterializeのCSSをベースに作っています。<br /> アイコンはGoogleの<a target="_blank" rel="nofollow noopener" href="https://material.io/tools/icons/">Material Design Icon</a>ですね。</p> <p>右上に「チュートリアル」っていうのがありますね。<br /> これを押します。</p> <p><a href="https://crieit.now.sh/upload_images/0f720b218ef49eb9945bad48c258e01b5c0d0e6579950.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0f720b218ef49eb9945bad48c258e01b5c0d0e6579950.gif?mw=700" alt="tutorial.gif" /></a></p> <p>チュートリアルが始まりますね。これは<a target="_blank" rel="nofollow noopener" href="https://introjs.com/">Intro.js</a>を使っています。</p> <h3 id="人物一覧"><a href="#%E4%BA%BA%E7%89%A9%E4%B8%80%E8%A6%A7">人物一覧</a></h3> <p><a href="https://crieit.now.sh/upload_images/38240eeecb79b980e3cdada069a0dabf5c067db0f06e6.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/38240eeecb79b980e3cdada069a0dabf5c067db0f06e6.jpg?mw=700" alt="characters.jpg" /></a><br /> 人物一覧に入ると人物のカードがバーッと表示されます。</p> <p>……<br /> <a href="https://crieit.now.sh/upload_images/5bdeb420d4d5375821ea7ce50205ad965c0d0fd370c59.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5bdeb420d4d5375821ea7ce50205ad965c0d0fd370c59.gif?mw=700" alt="characters2.gif.gif" /></a><br /> この状態でブラウザーを狭めてみましょう。</p> <p>はい、良い感じに並び変えられましたね。</p> <p>これは<a target="_blank" rel="nofollow noopener" href="https://masonry.desandro.com/">Masonry</a>というライブラリを使っています。</p> <p>うまく余白を見つけて要素を並べてくれます。<br /> このライブラリはすごいお気に入りで、昔からずっと使っています。</p> <p>ちなみに左側にサイドメニューが出ていますが、ここはVue.js + Elementになっています。</p> <p><a href="https://crieit.now.sh/upload_images/ef664ac4064c98d39520de0daccbda945c067eea94ef9.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ef664ac4064c98d39520de0daccbda945c067eea94ef9.jpg?mw=700" alt="sidemenu.jpg" /></a><br /> わかりにくいですが、「キャラクター」をクリックするとAPIを呼んでロードします。動的にこういうのが簡単にやりたかったのでVueにしました。</p> <p>jQueryでガンガン作ってサービスをリリースした後で「Vueいいじゃん!」って気づき、今は新しく作った部分から徐々に置き換えている感じです。</p> <p>次にいきます。</p> <h3 id="キャラクターの並べ変え"><a href="#%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%81%AE%E4%B8%A6%E3%81%B9%E5%A4%89%E3%81%88">キャラクターの並べ変え</a></h3> <p>キャラクターの「並び順を変更する」ではドラッグ・アンド・ドロップで直接キャラクターの並び順を変更できます。<br /> <a href="https://crieit.now.sh/upload_images/2c7b5bd1cfe466def868ac9d25c6f3975c0d1366ae270.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2c7b5bd1cfe466def868ac9d25c6f3975c0d1366ae270.gif?mw=700" alt="sortable.gif" /></a></p> <p>これは<a target="_blank" rel="nofollow noopener" href="https://github.com/SortableJS/Sortable">SortableJS</a>というライブラリを使っています。</p> <p>Vueでも使えるので便利です。<br /> 次です。</p> <h3 id="経歴"><a href="#%E7%B5%8C%E6%AD%B4">経歴</a></h3> <p>人物を掘り下げていくと「経歴」というマークダウン形式の入力欄が登場します。<br /> <a href="https://crieit.now.sh/upload_images/7e98a9349e3c82e9fb6697381f9dd0d35c068391e6b6b.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7e98a9349e3c82e9fb6697381f9dd0d35c068391e6b6b.jpg?mw=700" alt="markdown.jpg" /></a><br /> これは<a target="_blank" rel="nofollow noopener" href="https://simplemde.com/">SimpleMDE</a>です。</p> <p>他にも幾つかマークダウンのライブラリはありますが、これは日本語も無難に使えて良い感じです。</p> <p>次にいきます。</p> <h3 id="印刷用ページ"><a href="#%E5%8D%B0%E5%88%B7%E7%94%A8%E3%83%9A%E3%83%BC%E3%82%B8">印刷用ページ</a></h3> <p>記録されているすべての情報を印刷するためのページがあります。<br /> <a href="https://crieit.now.sh/upload_images/6b204ee3c10b8a4f108632023f44544a5c0d119cd4836.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6b204ee3c10b8a4f108632023f44544a5c0d119cd4836.jpg?mw=700" alt="print.jpg" /></a><br /> 印刷用のレイアウトを作成する必要があったので、ここでは<a target="_blank" rel="nofollow noopener" href="https://github.com/cognitom/paper-css">paper-css</a>を使っています。</p> <p>クラスを当てるだけで良い感じに幅や高さを調整してくれるのでとても便利です。</p> <p>次。</p> <h3 id="アイデアボード"><a href="#%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2%E3%83%9C%E3%83%BC%E3%83%89">アイデアボード</a></h3> <p>画像やふせんをペタペタ貼ったりする機能です。</p> <p><a href="https://crieit.now.sh/upload_images/8661e368e0a8654166899a6cb4fca58c5c06842d953a0.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8661e368e0a8654166899a6cb4fca58c5c06842d953a0.jpg?mw=700" alt="ideaboard.jpg" /></a><br /> よく見るとわかるのですが、ふせんの中にふせんをおいたりして親子関係にすることができます。</p> <p>ここは、割と初期に作った機能で、jQueryと<a target="_blank" rel="nofollow noopener" href="https://jqueryui.com/">jQuery UI</a>あたりでひたすら作りました。</p> <p>画像のアップロードは<a target="_blank" rel="nofollow noopener" href="https://www.dropzonejs.com/">Dropzone.js</a>ですね。</p> <p>この辺の作り方については<a target="_blank" rel="nofollow noopener" href="https://qiita.com/iotas/items/fbf4994877e5c2053787">Qiita</a>に記事を書いているので、興味があればこちらもご参照ください。</p> <p>続きます。</p> <h3 id="小説の宣伝ページ"><a href="#%E5%B0%8F%E8%AA%AC%E3%81%AE%E5%AE%A3%E4%BC%9D%E3%83%9A%E3%83%BC%E3%82%B8">小説の宣伝ページ</a></h3> <p>この機能はあまりちゃんとした名前をつけていないのですが、入力したテキストを分析して頻出単語や単語同士の繋がりを見ることができるページです。</p> <p><a href="https://crieit.now.sh/upload_images/3809c0b62d167539cc8df111b60168a45c0684f22d164.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3809c0b62d167539cc8df111b60168a45c0684f22d164.jpg?mw=700" alt="textanalyzer.jpg" /></a></p> <p>テキストはS3に上げて、AWS Lambdaで文章を解析しています。</p> <p>文章解析ですがほとんど独自ロジックはなくライブラリに依存しています。もうほとんど覚えてないですがコードを見る限りは<a target="_blank" rel="nofollow noopener" href="https://www.nltk.org/">nltk</a>を使っているようです。</p> <p>このライブラリを使う際に日本語の形態素解析を行う必要がありますが、こちらは<a target="_blank" rel="nofollow noopener" href="http://mocobeta.github.io/janome/">janome</a>を使っています。</p> <p>頻出回数とか、文章内での単語と単語の生起具合を解析している風に見えます。</p> <p>グラフの描画は<a target="_blank" rel="nofollow noopener" href="https://d3js.org/">d3.js</a>です。<br /> d3は上手く使うと少ない労力でインタラクティブなページが作れるので重宝しますね。</p> <p>続きます。</p> <h3 id="世界地図作成機能"><a href="#%E4%B8%96%E7%95%8C%E5%9C%B0%E5%9B%B3%E4%BD%9C%E6%88%90%E6%A9%9F%E8%83%BD">世界地図作成機能</a></h3> <p>WorldTypeからはまだリンクを貼っていないんですが、<a target="_blank" rel="nofollow noopener" href="https://www.world-type.com/terrain/">ここ</a>にあります。<br /> <a href="https://crieit.now.sh/upload_images/fd3851f2a5286041ab8f999083595b515c0687d94e5c4.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/fd3851f2a5286041ab8f999083595b515c0687d94e5c4.jpg?mw=700" alt="terrain.jpg" /></a><br /> オリジナルな世界地図を自動で作る機能です。</p> <p>これは特殊なライブラリを使っているわけではなく、ひたすら計算しまくってCanvasにガシガシ描画しているだけです。</p> <p>ざっくりとしたロジックですが、<a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/%E3%83%9C%E3%83%AD%E3%83%8E%E3%82%A4%E5%9B%B3">ボロノイ図</a>と<a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%AD%E3%83%8D%E3%83%BC%E5%9B%B3">ドロネー図</a>を使って点から「面」を作成。後は標高を上げたり下げたりして水の流れを計算して、大地を浸食させたり結合したりするとこんな感じになります。</p> <p>型がないとつらかったのでこの辺りはTypeScriptで書いてます。</p> <h3 id="終わりに"><a href="#%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%AB">終わりに</a></h3> <p>ここまで駆け足でWorldTypeを支える技術を見てきました。</p> <p>これだけの素晴らしい技術をオープンに提供してくださっている開発者の皆さんには本当に感謝の言葉しかありません。</p> <p>私も記事執筆などを通して少しずつ技術界隈に還元していきたいと思っています。</p> <p>明日は<a href="https://crieit.net/users/rubys8arks">かしい@お笑いSNS作成中</a>さんの記事です!</p> iotas𓆡創作支援アプリ運営中𓅬