まるまるこふこふ

数々の次元が崩壊し、全ての生命が塵と化すのを見てきた。私ほどの闇の心の持ち主でも、そこには何の喜びも無かった。

Yukkuri Talker を公開しました

Yukkuri Talkerという Webサービスを公開しました。(※ 2019/03/29 に閉鎖しました) Web 上で AquesTalk2 による合成音声(俗にいうゆっくりボイス)を再生/保存することができます。

f:id:sairoutine:20160712133238p:plain

技術スタック

Sails.js

Node.js のサーバーサイドフレームワークです。その名前の通り、 Ruby on Rails に強い影響を受けたフレームワークです。

mithril

クライアントサイドの JavaScript フレームワークです。 地味に HowTo や About へのページ遷移を SPA にしています。 ボイスの再生も、サーバーから音声バイナリを m.request で 受け取って、Web Audio API で再生しています。

gulp

browserify + msx でクライアントサイドの開発をよさ気に。 Sails.js が Grunt に依存しているので、Gulp と Grunt 両方混在してしまうのが難点。

AquesTalk2

合成音声ライブラリです。ライブラリなので、 C プログラムを書いて、 node.js からそのプログラムを叩くようにしました。 http://www.a-quest.com/products/aquestalk.html

bootstrap

Honoka の fork テーマ「Frandle」を使用しました。 http://sairoutine.github.io/Frandre/

努力と才能について所感

努力と才能

こんにちは。さいです。「努力」と「才能」よく対比される概念ですね。こちらの記事を読んで、努力と才能の話について思い出しました。

chokudai.hatenablog.com

先日、二人の競技プログラマが入社した。二人とも、TopCoderのAlgorithmのレーティングも僕より高い、格上の競技プログラマである。社長としては嬉しくはあるが、選手として見れば中々難しいところである。社内レーティングランキングが4位にまで転落してしまった。

まぁ、そんなことはどうでもいい。問題はここからだ。

彼ら二人の会話を見ていて思ってしまった。

「僕にはたどり着けるわけがなかった」と。

理由は極めて簡単。彼らのしていること。彼らの日常会話。それの、ほぼ全てが、「競技プログラミング」に繋がっているように見えたからだ。とにかく、数学的な、パズル的な、そんな思考を繰り返している。仕事中でも、仕事が終わっても。

持論の話なのですが、人が天才を見て、どうして天才と感じるのかといいますと、別にその人の結果がスゴイだけでは天才とは恐らく感じないと思います。人はなにかしら目標に向けて時間を費やしており、その延長線上にスゴイ結果にたどり着く未来が思い浮かべられれば、天才とは感じません。

天才とは、その人の行動や習性が明らかに異質で、かつ圧倒的な結果を出していると、人は「この人には勝てない」と感じます。明らかに自分とは異なる行動で、自分より先に目標にたどり着いている人間を見ると、今の自分の努力方法ではその成果に辿りつけないと考えます。

努力と才能というのは人によって定義が曖昧で、定義によって、論じる内容も異なってしまうので、一旦今回の記事における努力と才能の定義について整理しておきましょう。

努力と才能についての定義では、こちらの動画の内容が僕はすごくしっくりきています。

www.nicovideo.jp

努力とは目的のための有意識的行動であり、才能とは無意識行動によって得られたもの

努力によって得られたものを成果、才能に至る言葉を習慣と名付ける

努力は過程で才能は結果

表にするとこういうことです。

過程 意識 結果
努力 有意識 成果
習慣 無意識 才能

努力とは過程であり、対として語るならば、同じ過程である習慣を語るべきであり、 努力は意識を持って行う行動、習慣は無意識に行う行動です。

努力による結果を成果と呼び、習慣による結果を才能と呼びます。

ここで習慣という言葉が出てきます。才能がある人間は、 頑張っている/努力しているという意識すらなく、 無意識に行う行動によって才能を積み重ねているということです。

無意識に習慣によって行う利点は、圧倒的に長い時間をかけられるということです。 才能も成果も、時間を費やした結果であって、努力 or 習慣のどちらかによって得たかの過程によって 結果をカテゴライズしたに過ぎないのですが、努力に比べて習慣の方が圧倒的に長い時間をかけられる分、 才能の方が成果より大きくなることが多いです。

つまり天才とは、頑張っているという意識すらなく、無意識による行動で才能を積み上げて評価される人あり、努力家とは、やる気ドリブンで成果を積み上げて、積み重ねて評価される人です。

上記画像は、主題とはちょっとズレる画像ではあるのですが、やる気というのは出たり出なかったりする運要素であることを述べています。有意識であるがゆえに継続し続けることに非常にエネルギーを費やします。

僕は、競技プログラミングをやっていた、といっても、業務で触れていただけだ。日常ではない。だが、彼らにとってはそれが日常だった。

僕は「競技プログラミングの選手」ではあったかもしれない。だが、彼らのような「競技プログラミング星人」ではなかった。それがこの差なんだなぁ、と、ここ数か月で非常に感じた。

少し前の僕は「才能が違うのかな」と思っていた。そんなんじゃない。才能だったら自分だってある程度はある。致命的に違うのは、生き様だ。

なるほど。これは勝てるわけがない。

高橋直大さんが述べているように、これが努力と習慣の違いです。ここで述べられている日常/生き様が 私の述べる習慣のことだと考えています。日常/生き様レベルで目標に向けた行動ができる人は、 努力に比べて圧倒的に長い時間を費やせるので、結果も圧倒的に大きくなります。

どうすればいいのか

さて、努力と才能の話にて「才能とは、習慣による圧倒的長い時間を費やして生み出されたものである」という話をさせていただきました。 それを踏まえて、僕達はどうすればいいのでしょうか?

1つは、同じように習慣によって圧倒的時間を費やすことです。今努力して行っていることを習慣化してしまいます。 日常の行動は全て自分が目指している目標のために費やし、それ以外の行動は全て捨ててしまいます。

また自分の周囲の環境も変える必要があると思います。自身が当然としている行動基準が、 他の人からすれば異常じみてることを知れば、無意識に行動基準を下げてしまうのが、社会性のある人間の習性です。

天才とは自分が普通であると疑わない愚か者でなくてはならない

先ほどの動画でも述べられています。

X分野における天才に、X分野で真っ向からぶつかっていく方法もあります。一方、 X分野のうちの x1 にフォーカスしてぶつかっていく方法もあります。 高橋直大さんもそういう方向で勝負していくようですね。

他にも X分野だけでなく、Y分野も身につけて、X+Yで勝負していく方法もあります。この辺、X分野の天才とどう戦っていくかは人それぞれだと思います。

私は愚かなので、もう少しX分野に真っ向からぶつかっていこうと思います、今有意識的に行っている行動を無意識に行えるようにすることで。

終わり

今回のお話では努力について、「方法について考えながら努力すること」を、努力と呼びました。「何も考えず愚直に練習を重ねることを努力と呼び、そうした努力をするべきでない」と唱える人もいますが、今回の話ではそちらの努力の話はしませんでした。

ゲームエンジン AIMS を触ってみる 2

Mac への lua コンパイラのインストール

homebrew でインストールできるので、これだけ。

brew install lua

わたしは vim での構文チェックに syntastic を使用してますが、 lua コンパイラを入れると、luaスクリプトを開いた時/保存したときに 自動で構文チェックしてくれるようになったので、 特に追加でプラグインを入れなくても、これで満足です。

Mac 上で Windows を動かす。

Mac 上で AIMS製ゲームの動作確認をできるようにします。 VirtualBox 上に windows 10 を入れて、その上でゲームを動かすようにします。

VirtualBox は、複数の仮想マシンを作成し動作させることができる無償のアプリケーションソフトウェアです。 このアプリケーションを使って、Windows 10を、Mac のゲストOSとしてインストールします。

Win10 の ISO ファイルは MS の公式Webサイトからダウンロードできます。

https://www.microsoft.com/ja-jp/software-download/windows10ISO

windows 上で AIMS を動かす

AIMS サンプルプログラム「Suica32」を Win10 on Mac で動かしてみます。

http://aims.dna-softwares.com/?page_id=14

とはいえ、特に必要な設定もなく、公式から「Suica32」をダウンロードしてきて、 AIMSのZIPファイル中にある”bin\AIMS_dev.exe”もしくは”bin\AIMSd.exe” を suica32\AIMSd.exe としてコピーしたのち、AIMSd.exeを起動するだけです。

サンプルプロジェクトを作る

AIMS ディレクトリの中に 「proto」というディレクリがありますが、 これを利用すると、簡単にサンプルプロジェクトが用意できます。

Mac <-> Win10 でのプログラムファイルのやり取りは githubを 介して行おうと思います。 proto ディレクトリを git 管理します。

win10 に git をインストール

こっからDLしてきてインストールするだけです。 https://git-for-windows.github.io/

プロジェクト内に以下のバッチファイルを置いておきましょう。

gitpull.bat

git pull --rebase

これで Win10 上で動作確認する際、コマンドラインを開いて わざわざ git pull しなくても、バッチをダブルクリックするだけで 最新の変更を落としてこれます。

ゲームエンジン AIMS を触る 1

こんにちは、さいです。
同人ゲームを作らせて頂く機会を得たので、ゲームエンジンを使って
ゲームを作ろうと思います。

今回ご紹介させていただくのは、「ゲームエンジン AIMS」です。

AIMS

AIMS は 2Dのアクション主体のゲームを作成するためのエンジンです。
特徴的なのは、Lua言語でゲームロジックを記述するところです。

D.N.A.Softwaresさんが開発しています。
面白いのは、商業で使われているゲームエンジンではないんですね。
D.N.A.Softwares さんは同人サークルです。

とはいえ、長く歴史のある同人サークルさんで、
AIMS を利用して、これまでたくさんのゲームをリリースされていらっしゃいます。

公式サイトから引用させていただきますが、AIMSが得意とするジャンルは以下です

・2Dゲーム全般
シューティングゲーム
アクションゲーム
テーブルゲーム
etc...

他にもたくさんの2Dゲームを作ることができます。詳細は公式

またドキュメント類もしっかりしてて、公式にリファレンスがあるのはもちろん、
ガイドブックも pdf で販売されております(2016/06現在)

gumroad.com

なぜ?

世間ではゲームエンジンといえば、Unity とか UE4 がメジャーなようですが、
なぜ AIMS を選択するのか?

  1. 技術的興味
    C++ のようなコンパイル型言語から、Luaのようなスクリプトを動的ロードすることに興味があり、 まずは Lua を触ってみたかった。

  2. 開発環境構築の容易さ
    Unity や UE4 の開発環境構築は大変です。エディタも 使用できるエディタは実質限られてしまいます。 (※僕は触ったことがないため、完全に第一印象だけで 喋ってるのでツッコミ希望です)
    おまけに僕はGUIが苦手です。やりたいことが全てコードを通して命令できることを望みます。 AIMS は Lua で記述できます。Luavim で編集できます。 ちょっと工夫すれば、Mac 上で動作確認もできます(これについては別の機会に書きます) いわゆるオーソドックスな webプログラミングの開発環境を流用できそうなところが魅力的でした。

  3. 薄い
    AIMS はフルスタックにゲームエンジンとしての機能を 何もかも揃えているわけではありません。 デメリットのように見えて、それは覚えるべきAPIが少ない点で、 学習コストが低いというメリットになります。

リンク

AIMS Headquarters

D.N.A. Softwares

次回

Mac + vim での開発環境構築について書ければと思います。

sails で migrate されるテーブルのカラムの型定義

さいです。

サーバーサイドのフルスタックMVCフレームワークの sails.js を触ってます。
フルスタックなので migrate 機能があります。
モデル定義するだけで、アプリケーション起動時に自動でテーブル作ってくれるヤツですね。

sail.js のモデルは Waterline なのですが、どのストレージでも同じ型定義で記載できるよう、
integer とか string とかそんな型定義しかありません。

具体的に MySQL でどんな型になるんや!となったので調べました。

Watarline の型定義 -> MySQLの型定義の変換は sails-mysqlモジュールの
lib/sql.js にあります。

v0.12.1 時点だと以下のようになってるっぽいです。(大文字小文字問わない)

type size MySQL上の型
string N(省略した場合 255) varchar(N)
text LONGTEXT
array LONGTEXT
json LONGTEXT
mediumtext mediumtext
longtext longtext
boolean BOOL
integer 8 TINYINT
integer 16 SMALLINT
integer 32(デフォルトサイズ) INT
integer 64 BIGINT
float FLOAT
double FLOAT
decimal DECIMAL
date DATE
datetime DATETIME
time TIME
binary BLOB

ざっと見たけど、 unsigned を数値に設定する方法はないっぽかった。。。

同人誌即売会向けレジアプリ「レジプラ」を例大祭13で使用しました

f:id:sairoutine:20160508213459j:plain

こんにちは、さいです。

わたくし、趣味事として同人サークルを営んでおり、 東方Projectアイドルマスター等のキャラクターの グッズを制作して、同人誌即売会で販売しております。

https://sai-chan.com/rubberstrap.html

2016/05/08 に開催された 東方Projectオンリー同人誌即売会 博麗神社例大祭においても サークル参加してグッズを頒布させていただきました。

ところで、Twitter レジプラさんの下記のようなツイートを拝見しまして、 モニター登録をお願いしたところ、例大祭で使わせて頂けることになりました。

こんな感じでレジプラ土台と、さらにアプリインストール済みのiPhoneを貸して頂けました。

f:id:sairoutine:20160514213839j:plain

土台の中はこんな感じ。スイッチを入れるとコードレスで、 レジプラ土台とiPhone が接続されます。便利!

f:id:sairoutine:20160514214141j:plain

レジプラの商品登録画面

f:id:sairoutine:20160514214817p:plain

商品一覧画面

f:id:sairoutine:20160514214833p:plain

4つ目以降の商品はスライドさせると出てきます

f:id:sairoutine:20160514214902p:plain

お会計はこんな感じ。お釣りの額も自動で表示してくれるのがイカス!

f:id:sairoutine:20160514214913p:plain

そんな感じで、会場ではこんな感じで置いておりました。

f:id:sairoutine:20160508093936j:plain

弊サークルの名物、机を寂しく見せないために とりあえずグッズを並べるの図。

f:id:sairoutine:20160508093929j:plain

おかげさまでたくさんの方に足を止めて頂き、 盛況に終わりました!

レジプラさん、モニターとして使わせて頂きありがとうございました! 正式に販売される日を楽しみにしております!

f:id:sairoutine:20160508213459j:plain

当日、胸に貼ってたサークル参加証。 サークル参加証の入ったかばんを電車に忘れて、 再発行してもらうアホっぷりだった……

MySQL サーバーを再起動するとAUTO_INCREMENT の値が戻る

InnoDB では AUTO_INCREMENT のカウンタはメモリ上に保持します。

14.6.5.1 従来の InnoDB の自動インクリメントロック https://dev.mysql.com/doc/refman/5.6/ja/innodb-auto-increment-traditional.html

InnoDB テーブルに AUTO_INCREMENT カラムを指定すると、InnoDB データディクショナリ内のテーブルハンドルに、カラムに新しい値を割り当てる際に使用される自動インクリメントカウンタと呼ばれる特別なカウンタが含まれます。このカウンタは、ディスク上には格納されず、メインメモリー内にのみ格納されます。

InnoDB では、ai_col という名前の AUTO_INCREMENT カラムを含むテーブル t に自動インクリメントカウンタを初期化するために、次のようなアルゴリズムが使用されます。サーバーの起動のあとで、テーブル t への最初の挿入をするために、InnoDB は次のステートメントと同等なものを実行します。

SELECT MAX(ai_col) FROM t FOR UPDATE;

何が問題かというと、最新のレコードを削除して MySQL サーバーを再起動すると AUTO_INCREMENT の値が巻き戻る。

>select * from test;

1
2
3
4
5

>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

>delete from test where id = 5;
>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

ここでMySQLを再起動

>show create table test;
CREATE TABLE `test` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

まあこのように SELECT MAX(id) FROM test FOR UPDATE; の値に巻き戻る。 AUTO_INCREMENTした値が一意であることを見越して、
他のテーブルの外部キーにしてたりすると、整合性が取れなくなってしまう。

対策としては
・外部キー制約入れる
・AUTO_INCREMENTに頼らず、別に採番テーブルを用意する
・論理削除してレコードを delete しない(!)