2020年12月24日木曜日

TinyMSX

MSXであってMSXではない謎エミュレータ(TinyMSX)を作ってみました。

https://github.com/suzukiplan/tiny-msx

TinyMSXは、以下のゲームを動かすことができます。

  • SG-1000
  • Othello MultiVision
  • MSX1 (16KB/32KBカートリッジ) ※メガロムは現時点では未対応

オセロマルチビジョンはオマケ。

SG-1000実機を持っている人はレアというか、相当な物好きに限られると思います。1983年7月15日に発売されました。

発売日が任天堂のファミコンと同じ日なので、どうしても比べたくなるのが人の性...

(SG-1000 vs ファミコン)

  • 値段: ほぼ同額だがファミコンの方が200円安い
  • CPU: Z80A vs 6502 ... どちらかといえばZ80の方が高性能
  • 画像処理: TMS9918A vs 独自PPU ... ファミコンの方が表現力が高い
  • 音声処理: SN76489(PSG) vs 独自APU ... ファミコンの方が表現力が高い
SG-1000がファミコンに勝っていた点はCPUのクロックレートだけで、値段、グラフィック、サウンドの面ではファミコンが圧倒的に高性能でした。

    CPUのクロックレートについても、ファミコンのRP2A03(約1.79MHz)の命令の方が全般的に低いサイクル数で命令が実行できたので、SG-1000のZ80A互換(約3.58MHz)が勝っていたとは言い難いです。Z80はパソコン向きに設計されているCPUなので、レジスタが沢山あったり、16bit演算ができたり、ループ命令があったりと機能的に複雑だったこともあり、1命令あたりの消費クロック数が高い欠点がありました。加えて、ファミコンはただでさえシンプルな6502から更にBCDモードの機能を取っ払っています。

    画像処理については、

    • 表示スプライト数: SG-1000は32個 vs ファミコンは64個
    • スプライト色: SG-1000は単色+透明 vs ファミコンは3色+透明
    • 水平スプライト数の上限: SG-1000は4個 vs ファミコンは8個
    • BGの色: SG-1000は横8pxにつき2色 vs ファミコンは1キャラクタに4色
    • BGのスクロール: SG-1000はナシ vs ファミコンはアリ
    • BGのプライオリティ: SG-1000はナシ(スプライトが常に前面)vs ファミコンはアリ

    という具合。

    SG-1000(TMS9918A)が唯一勝っていた点はスプライトのサイズが豊富だったことぐらい(ファミコンは8x8 or 8x16だったのに対してSG-1000は8x8, 16x16, 8x8の2倍, 16x16の2倍)だと思います。

    あと細い所ではファミコンだと0番スプライトの描画検出によりスキャンライン描画タイミングを捕捉できたので、標準機能のみでIRQライクなことができたので、ラスタースクロールが可能です。(IRQについては拡張マッパーで使うこともできました)

    音声については、SG-1000はPSG(AY-3-8910)を若干簡素化したSN76489(矩形波3+ノイズ1)なのに対して、ファミコンは矩形波2+三角波1+ノイズ1+ADPCMで更に矩形波はデューティー比を変更することでノコギリ波に似た音色を出すことができました。

    つまり、用途を「ゲーム」に特化して考えれば、SG-1000がファミコンに勝てる要素はほぼ皆無で、尚且ファミコンよりも微妙にお値段が高いので、この事実だけ見れば「SG-1000はファミコンに負けて当然だね」と思えるかもしれません。

    ただ、SG-1000がファミコンに勝てる芽が一切無かった訳ではないと思われます。

    SG-1000が搭載している装置(Z80, TMS9918A, SN76489)は、独自アーキテクチャで固められたファミコンと比べてゲームを作れるプログラマの人口が(当時は)多かったので、コンテンツ供給力では1983年時点ではSG-1000の方が優位に立っていたと思われます。また、SG-1000とファミコンが発売された1983年には、ASCIIとマイクロソフトが共同で開発したMSXが発売されましたが、MSXもSG-1000とほぼ同じハードウェア構成(Z80, TMS9918A, AY-3-8910)だったことも追い風になったかもしれません。

      ただ、結果的にSG-1000で発売されたタイトルはほぼ全部自社タイトル(一部、オセロマルチビジョンのツクダオリジナル製品もある)で占められていました。当時は現在のようにサードパーティーが参画するという発想自体が無かったのですが、サードパーティーを積極的に取り込む戦略だったら、未来は少し違っていたかもしれません。

      それでも私がSG-1000にめちゃくちゃ思い入れがあるから自らエミュレーターを作った・・・ということであれば美談になるのですが、実はそうでもなく、自作のZ80エミュレータを使ったゲーム機のエミュレータをOSSで作っておきたかったので、ハード構成が単純で作りやすいMSX1 & SG-1000をターゲットにしてみただけだったりします。

      2020年11月25日水曜日

      運動中は消化の良いものを食べましょう

      20km前後のサイクリングにだいぶ慣れてきたので、そろそろ50km超えをトライしてみようということで、三連休の半ばに彩湖を目標にサイクリングしてきました。

      AM10:00に出発して12:00頃に到着。

      到着後、GoogleMapで近所の適当なファミレスを探索。23区内ならランダムエンカウントで問題無いけど、流石に埼玉(朝霞市)でそれは無謀だろうということで。(実際、GoogleMapを使っても結構探索に手間取りました)

      昼食はドリンクバーでジュースを飲みつつピザをチーズ増量&ポテト付きで食べたのですが、これがマズかった。いや、味は美味しかったのですが、これが原因で帰宅後に地獄を見ることになるとは、この時は思いもよらなかったのです。

      約1時間の食事休憩後、朝霞市内を適当に周り、朝霞大橋を渡った所で折返して16:00過ぎに帰宅。

      走行時間は5時間ぐらい。道程の8割ぐらいは荒川サイクリングロード(仮称)だから信号停止とかが無いので、確実に平均時速10km以上は出ていた筈(もっと速いかも?)だから、恐らく50km以上走った筈です。(次はちゃんとサイクリングコンピュータとかを使おう...)

      初めて50km以上走ったものの、足は思っていたよりも筋肉痛にはならなかったので、もっと先まで行けたかも。ただし、何故か腕が筋肉痛になりましたが。

      筋肉痛は想定内なので問題無いのですが、帰宅後から謎の腹痛がして気持ち悪い。

      何だこれ?

      まぁ、動けないレベルではないし、時間が経てば自然と治るだろう...と、早め(21:00頃)に就寝したのですが、腹痛がひどくなるばかりで寝付けず、24時を過ぎたあたりで「これ、危ないヤツではないか?」と思い始めました。

      想定外の体調不良というのは中々怖い。

      ネット上の医療情報を漁って「激しい運動をすると内蔵がぐちゃぐちゃになるから補給は消化を良いものを」みたいな記事を見て「あ、昼食のピザがアカン奴だったのでは?」と気づく。幸い手元に緩下剤(夏に受けた健康診断で貰ったヤツの残り)があったのですが、先ずは薬には頼らず、民間療法で何とかすることにしました。

      ネットで「便秘に効くストレッチ」みたいなものを参考にストレッチしたり、DAKARAを飲んでみたり、タバコを吸ったり色々試したAM2:00過ぎ、ようやく変わり果てたピザ(宿便)との再開を果たし、無事腹痛が収まりました。

      うーん、こわい。

      じゃなくて、運動する時の補給には気をつけましょう。

      恐らく、今回のように中間地点で補給する場合、ゼリー状のヤツとかが良さそう。ファミレスやファーストフードに寄るなら若干のクールダウンを挟んだ後のタイミングで。固形食を摂る場合は咀嚼回数を普段の倍程度しつつ、すぐに動かない(長めに休憩する)ようにすれば問題無かったかもしれない・・・まぁ、何の医学的な根拠もないカンですが。問題が発生したら原因を特定して対策を実施、治ったら再発防止処置を講じるといういつものやり方。

      2020年11月21日土曜日

      本日のサイクリング

      ふと海が見たくなり、自宅から荒川サイクリングロード(通称)で葛西方面まで行ってきました。

      今日はかなり風が強かった(強風注意報が出てました)のですが、行きは追い風だったので割とすぐに荒川サイクリングロードの先っぽまで到着。(距離にして自宅から13kmぐらい)

      写真は中川側(だから余計に)ですが、海っぽさが足りない...

      強風が内陸から海側方向だったので、潮風が全部吹き飛ばされてしまったのかも。

      かといって、ここから潮風が感じられる千葉 or 神奈川方面まで行く体力は多分無いので、そのまま葛西臨海公園をぐるりと回って行こうかと思いましたが、良い感じの時間(12:45頃)だったので、餌場を求めて江戸川区の市街地へ。

      ただ、運悪くココス的な感じのファミレスにエンカウントせず只管北上。結局、四ツ木あたりまで北上したところでようやくジョナサンを見つけてIN。(14時30頃)

      GoogleMapとか使えば良いのですが、テクテクライフを動かしながら彷徨っていた関係で、ファミレスエンカウントは(土地勘が無いところでは)完全に運ゲーです。テクテクライフを動かす所=土地勘が無い所なので、餌場探しの難度が中々高いです。(嫌いではありません)

      2020年10月26日月曜日

      MODサイバーセキュリティ要員を募集中らいし

       MOD(防衛省)がサイバーセキュリティ要員の募集をかけてます。

      https://www.mod.go.jp/js/saiyou/pdf/s20201007_01.pdf

      確か、今年の2月ぐらいにも同じ募集があったような気がしますが、集まらなかったのかなぁ...

      菅内閣になってから、デジタル移行が重要視されており、その絡みもあって単純にサイバーセキュリティ要員が不足しているから追加募集という風にも考えられますが、前回の募集と違ってお賃金の額が例示されている点が気になる。

      募集条件は割と緩いです。

      • 正社員(or官公庁の正職員)として勤続合計13年以上
      • 年齢制限あり
      • IPAのITスキル標準レベル3以上
      • 犯罪歴や懲戒歴等なしの日本人

      私は募集条件を満たしています。

      というか、母数(条件を満たしている人数)は普通に多いと思います。

      かなり興味があるのですが、今の仕事をちゃんとバトンタッチするなり終わらせるなりしてからじゃないと公務員にはなれないので中々悩ましい。公務員になると当然営利の副業はNGですが、営利じゃなくて無報酬であっても民間企業の手伝いはNGになる(憲法でそういう風に規定されている)ので難しい。

      なお、お賃金はお安め(個人的にはこの点は全然問題なし)

      ちなみに、この採用試験に合格できる人なら、民間でその気を出せば普通に倍以上稼げると思います。それでも尚、やりたいと思える=全体の奉仕者として働く熱意といった感じでしょうか。(もちろん、お賃金に限った話ではないですが。ただ、お賃金額を例示したということは前回募集ではその辺がネックになったのかな?などと邪推してしまう...防衛省職員のお賃金は法律で決まっているので、採用等級だけ示せば例示不要な筈で、前回募集でも「係長相当職員(行(一)3級)」と明示されていたので、載せる意味なんて無いのでは?と思うのですが...

      転職を考えてた2013〜2014年頃、丁度警察でも似たような募集(サイバー犯罪の調査員とかだったかな?)があって心揺らぎましたが、当時も似たようなことで悩んで結局民間企業に転職しました。当時抱えていた悩みどころは解消済みなのですが、今はタイミングだけが合わない。中途半端に仕事を投げ出せば不可能ではないですが、まぁ、それは性格的に無理です。

      つくづく、公務員とは縁が無いなぁ。(興味はあるのですが)

      2020年10月23日金曜日

      UIImagePickerControllerで許可を求められない件

       iOSアプリでフォトライブラリから画像を取得する方法として、

      1. UIImagePickerControllerを使用する方法
      2. PHPhotoLibraryを使用する方法
      という2種類の方法があります。(※どちらもiOSが提供するAPIです)

      違いとしては、前者(UIImagePickerController)はOSが提供するUIを利用するのに対して、後者(PHPhotoLibrary)はフォトライブラリからデータを参照する(UIを独自に実装する必要がある)という点にあります。

      なので、UIImagePickerControllerの方が手軽に使えます。

      UIImagePickerControllerは、iOS11から仕組みが大きく変わり、OSプロセスで写真を選択し、選択された写真をアプリプロセスへ返す形になりました。

      iOS10以前のUIImagePickerControllerは、アプリプロセスからフォトライブラリにアクセスしていたので、フォトライブラリへアクセスしようとしたタイミングで以下のような確認が求められていました。

      フォトライブラリのアクセス許可

      しかし、iOS11以降では許可が不要になりました。

      iOS11以降の場合、PHPhotoLibraryを使用しているアプリでのみフォトライブラリへのアクセス許可が求められます。

      (セキュリティ的にどちらが安全か?)

      仮に信頼できないアプリを利用する時、UIImagePickerController(許可不要)とPHPhotoLibrary(許可が必要)のどちらが安全でしょうか?

      UIImagePickerControllerは、許可自体不要ですが、許可をしていない以上アプリが勝手にフォトライブラリをアクセスすることは出来ません。

      一方、PHPhotoLibraryは必要なタイミングで許可を与えなければならず、許可を与えてしまった以上どのような目的でフォトライブラリにアクセスされるか分かりません。

      なので、セキュリティ的にはUIImagePickerController(許可不要)の方が安全です。

      セキュリティ意識が高い方は、iOS11以降ではフォトライブラリへのアクセス許可を求めてくるアプリに基本的に許可を与えないようにすることをオススメします。何が抜かれるか分からないですからね。必要に迫られて許可を与える場合は「写真を選択...」を選んで、アプリにアクセス権限を与えても良い写真のみ選ぶと良いです。(私は抜かれて困る写真は入っていないので割とホイホイとフルアクセス許可を与えてますが...これはこれで寂しい)

      以下の記事で、「iOS11からUIImagePickerControllerで許可が求められなくなったので、PHPhotoLibraryで許可を求めるようにした(そうしないとリジェクトされるかも)」という内容が紹介されていたのですが、UIImagePickerControllerを使って許可を求めない分にはリジェクト対象にはなりません。(何故なら、アプリではフォトライブラリに直接アクセスしていないのでAppStoreのレビューガイドライン違反になりません)

      https://qiita.com/Masataka-n/items/468a38379c3f3bf132ca

      そもそも、PHPhotoLibraryで求める許可は、PHPhotoLibraryでフォトライブラリへアクセスするためのものです。フォトライブラリへのアクセス権限には「全部許可」「一部許可」「許可しない」の3種類が現在(iOS14では)ありますが、例えば「一部許可」した状態でUIImagePickerControllerを起動しても一部ではなく全部の写真が表示される「許可の矛盾状態」が起きます。ユーザ視点で見ても「許可していない写真が見えている」と不安になるのではないでしょうか。要するにUIImagePickerControllerを用いるためにPHPhotoLibraryでアクセス許可を求める実装はNGです。

      PHPhotoLibraryでアクセス許可を求めるならPHPhotoLibraryでPHAssetsへアクセスする独自UIを作るべきです(・・・が、写真を選ぶだけなのにわざわざUIImagePickerControllerを使わずにアクセス許可を求めてくる方が、「このアプリはセキュリティ的に大丈夫なのだろうか?」と個人的には不安に思ってしまいます)


      以下のフォーラムで、Appleフレームワークエンジニアが同じようなことを言っています。個人的には日本語でヒットする記事よりも、Appleフレームワークエンジニアの回答が全面的に正しいと思ったので、今回記事にしてみました。

      https://developer.apple.com/forums/thread/653414

      (Appleフレームワークエンジニアの回答を引用) 

      UIImagePickerController runs out-of-process since iOS 11. There is no need to prompt for Photos Library access before showing the picker on iOS 11 and above, unless you really need to work with the selected PHAssets.


      As outlined in this years session, there are some considerations for using the picker with Limited Library:


      > The picker will still show the entire Photos Library and all photos and videos can be selected by the user. No matter what the users selects in the picker, the PHAssets you can access will not change.


      There is no support to only show assets in the picker that you app has access to when in Limited Library mode. 

      Please feel free to provide feedback and outline the use case where your app would need to further restrict the selection.

      2020年10月18日日曜日

      iOSサブスクリプション実装後に心臓に悪い日々を過ごさなくて済むために読んでおいた方が良い記事

       先日、本業でAppStoreサブスクリプションに対応したサービスをリリースしたのですが、クライアント側の実装に大きな問題があり、現在その対策版の審査待ちという状況です。初めて特急審査出してみました。既にサービス開始してしまっていることから、それだけでもかなり心臓に悪く、眠れぬ日々が続いております。

      今後ほかの方が同じ轍を踏まなくて済むように、一体どのような問題が起こり、どのような対処をしたのか可能な限りなるべくわかり易く書き記しておこうと思います。


      (AppStoreサブスクリプションの概要)

      サブスクリプションを定期購読すると「レシート」と呼ばれるものが発行されます。アプリでこのレシート取得して、自前のサーバへ送信&検証することで、ユーザが購読者か否かを判定する...というのが、基本的なサブスクリプション実装方法です。(詳細はコチラを参照)


      (今回発生した問題)

      定期購読したユーザがアプリを再起動すると、定期購読中と判定されない不具合が発生しました。

      つまり、買ったのに「買ってない」と判定されてしまう致命的なバグです。


      (問題の原因)

      アプリでレシートを取得するには、Bundle::appStoreReceiptURLというAPIを用いますが、どうもこのAPIがnilを返しているらしいことがサーバのログから判明しました。

      不思議なことに暫く時間を置いてからリトライすれば、正しい値が返されます。

      これと類似する現象が以下のStack Overflowで公開されていました:

      https://stackoverflow.com/questions/20027322/appstorereceipturl-on-mainbundle-always-returns-nil

      上記によると、

      SKReceiptRefreshRequest *refreshReceiptRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:@{}];
      refreshReceiptRequest.delegate = self;
      [refreshReceiptRequest start];

      という形でレシートをリフレッシュする必要があるとのことでした。

      ただし、上記実装ではローカル変数(弱参照)でSKReceiptRefreshRequestインスタンスを保持しているので問題があります。

      以下の記事にもありますが、SKReceiptRefreshRequestインスタンスは強参照(strong@propertyなど)で保持しなければなりません。

      https://asmz.hatenablog.jp/entry/in-app-purchase-not-working-in-tvos

      そこで、アプリ起動時(ログイン時)にSKReceiptRefreshRequestインスタンスをリクエスト中は強参照で保持しつつ、リクエストを出す形の修正をしてApple審査に提出しましたが、リジェクトされました。


      (審査リジェクト原因)

      リジェクト理由は、アプリ起動後にタップ(ログイン)したところハングアップした(ガイドライン2.1違反)とのことです。

      以下のStack Overflowに書かれていますが、AppStoreのsandbox環境でSKReceiptRefreshRequest::startを発行すると、クレデンシャルの入力が要求され、それをキャンセルすると二度と応答が返らない(アプリを一度削除してから再インストールする必要がある)とのことです。

      https://stackoverflow.com/questions/30114489/skreceiptrefreshrequest-not-working-the-second-time-it-is-called-after-a-cancel

      上記のAnswerに、

      The only solution is to present an alert, telling the user to remove and download your app again from the store and to not cancel the credential box when the app asks for the apple ID/password. 

      翻訳: 唯一の解決策は、ユーザーにアラートを提示し、アプリを削除して再度ダウンロードするように指示することと、アプリがアップルID/パスワードを要求したときにクレデンシャルボックスをキャンセルしないように指示することです。

      という、「そんなまさか!?」と思うようなことが書かれていますが、考えうる限りどうもそれが事実のようです。という訳で、Apple審査を通すため、SKReceiptRefreshRequest::startの裏でNSTimerをスケジュールして一定時間(60秒)応答が無かった場合は、「アプリを削除して再度ダウンロードするように指示することと、アプリがアップルID/パスワードを要求したときにクレデンシャルボックスをキャンセルしないように指示」する旨のアラートを表示するという、〇〇(自粛)のような修正を入れて審査再提出しました。


      (何故テストしきれないのか)

      根本的な原因は、sandbox版AppStoreと本番AppStoreの挙動に違いが多すぎることにあります。

      本番AppStoreでテストするには、一度Apple審査を通す必要があります。

      Apple審査を通せば「プロモコード」を発行することで、本番AppStoreの挙動をテストできるのでは?と思われるかもしれません(私もそう思っていた時期がありました)が、リリースしていないアプリの場合、プロモコードを発行してもアプリをダウンロードできないので、「ローンチ一発目はぶっつけ本番で一般ユーザと一緒にテストするしかない」という、非常にロックンロールな仕様になっております。

      だからバグっていても仕方がない・・・とは言いませんが、テストせずにバグを全て取り除くのは困難です。

      実は、今回の対策で本当に問題対策できているかという確証がまだ無いです(本番環境でテストできていないので当然ですよね)。なので、Apple審査(現在審査待ち)に合格したら、今度こそはプロモコードを使って事前テストしたいところです。できなければ、またロックンロールするしかないですね。(審査後にテストできてまた問題が見つかったら、また審査待ちで数日を要し、その数日間がまたハラハラドキドキになってしまいますが、「治ったよ」と宣言して治ってなかったというケースと比べればまだ安心・・・なのだろうか。連日の徹夜続きで既に思考が正常ではないかも)

      心臓に悪い日々はまだまだ続きそうだ。

      2020年9月16日水曜日

      移住検討

      現在、東京(千代田区)の会社に東京(足立区)のマンションからリモートワークをしていますが、そろそろマンションという高級サブスク(月額約8.5万円)にメスを入れることを考え始めました。

      「リモートワークが普及してもUターンする事例が意外と少ない」みたいな記事をチラホラ見ますが、最低1年ぐらいは状況を様子見しようと思っている人が多いのではないかと思います。(私もそのクチです)

      やはり、引っ越しは大変なので。

      (実際、去年大変でした...)

      社会情勢的に今の働き方で固まったと認識できた人々から徐々に、民族大移動していくのではないかと予測してます。

      私が現在住んでいる足立区は、家賃が安い割に(場所によっては)都心にも通いやすい良い所です。自宅最寄り駅(綾瀬)は千代田線の始発本数が多く、勤務先(大手町)まで乗換なしで20分程度で行けるので、リモートワークで無ければ恐らくベストチョイスだった筈です。

      綾瀬の1ルーム家賃相場は7.05万円ほど。

      都心への通いやすさを加味すればかなりリーズナブルだと思います。(私が引っ越してきた去年は6万円台だった気がするので最近少し上がったのかな?)

      しかし、「都心への通いやすさ」を考慮しなくても良いなら、もっと良い選択肢がある筈。

      という訳で、以下4パターンの移住候補を考えてみました。

      • 実家(静岡)
      • 千葉(総務快速線の駅近)
      • 別荘定住
      • 熱海あたりのリゾートマンション

      (候補1: 実家)

      • メリット: 家賃フリー
      • デメリット: 東京に通い難い(片道2〜3時間)

      都心に行く頻度は減ったとはいえ、取引先によっては「会議は対面で」って所もまだありますし、社用で出社しなければならないことが(ハンコ以外にも)しばしばあります。

      ハンコについてはさっさと日本から無くしたいのですが、ハンコ問題は取引先もセットで対応しないと意味がないので難度が高いです。「アナログハンコの契約書は法的に無効に出来る」とか、ある程度強制力のある形で公的に推進していかないと解決しないと思うので、法律を作る人たちに頑張っていただきたいです。いや、既にハンコ撲滅に向けて頑張って頂けているものと信じておりますが何卒...ハンコの陰影や筆跡なんてフォトショとかで簡単に偽造できるので、法的に無効化するための根拠は既にあるんじゃないの?と無責任なことを言ってみる。

      実際、リモートワークになってから約半年間で13回の出勤と1回の出張をしました。

      月平均にすると2.3回、週平均だと0.5回ぐらい。

      今ぐらいの頻度なら静岡からでも余裕ですが、これが月平均10回以上とかだったりするとキツイ。(流石に10回は超えなそうな雰囲気ですが)

      (候補2: 千葉)

      今後、出勤頻度が上がってしまうパターンの候補も一応考えてみました。コンセプトは今より少し通うのが大変になるけど家賃や生活費がお得そうなエリア(長い)です。

      そのコンセプトだと千葉あたりが良さそう。

      千葉と言ってもメチャクチャ広いですが、具体的には総務快速線エリアが東京へ通いやすくて良さそうです。

      千葉駅〜東京駅までは距離がそこそこ(だいたい38kmぐらい)ありますが、総務快速線は市川〜千葉の区間でトランザムするので、総務快速線沿いの物件なら東京にも通いやすくて家賃も安いです。

      現在の総務快速線沿線の家賃相場(ワンルーム・1k)を調べてみたところ、以下のような感じでした。

      • 錦糸町 9.54万円
      • 新小岩 7.24万円
      • ---- ここまでが東京(ここから千葉)----
      • 市川 6.77万円
      • 船橋 6.60万円
      • 稲毛 6.28万円
      • 千葉 6.40万円
      • 東千葉 5.14万円
      • 都賀 4.28万円
      • 四街道 5.11万円
      • 物井 4.13万円
      • 佐倉 4.82万円

      錦糸町より先(〜東京まで)は平均10万円以上なので省略してます。

      また、東京から先の神奈川方面(横須賀線)は、相当西側まで行かないと安くならないです。

      例外的に保土ヶ谷がそこそこ安め(5.49万円)ですが、あの辺は坂が多いので体力が無いとキツイかもしれません。駅伝で有名な権太坂が保土ヶ谷と東戸塚のちょうど中間地点ぐらいにあり、昔権太坂近辺の寮に住んでましたが、毎日坂を登っていたような記憶。寮長さんがバリバリの退役軍人だったらしく、カジュアルな軍隊気分のノリが味わえる良い寮でした。(ちなみに各部屋に風呂 and キッチンは無いですが、大浴場と食堂がありました)

      マッスルタウン(保土ヶ谷)を除けば、逗子を超える辺りまで行かないと安くなりません。逗子ですら平均7万円します。日立製作所の大きなIT関連の工場(?)が戸塚にあり、その関係であの辺は所得レンジが高いのではなかろうか...と勝手に想像してます。

      ついでに、神奈川方面なら横須賀線よりも東海道線の方が良いです。(当時、神奈川に住んでいた時の感覚では、横須賀線=鈍行、東海道線=快速みたいなイメージ)

      東海道線沿線なら大船(6.53万円)あたりが千葉とだいたい同じぐらいの家賃相場です。ただし、通勤ラッシュ時間帯の東海道線の混み方は尋常ではない水準でヤバかった記憶がありますが、今でもあのままなのだろうか...

      千葉〜東京の距離(約38km)に近い東海道線沿線の駅は戸塚(東京まで約40km)ですが、日立城下町戸塚の家賃相場はそこそこ高い(7.01万円)ので、神奈川 vs 千葉なら千葉(6.40万円)の方が微妙にお得です。

      (候補3: 別荘定住)

      • メリット: 豊かな自然etc
      • デメリット: 厳しい自然etc
      • デメリット: 場所によっては実家からより東京へ通い難い

      誰もが一度は憧れる(当社比)別荘定住も考えてみましたが、現実的には無理かなと。

      そもそも別荘を持ってないので想像ですが、やはり別荘は定住するものではなく、行楽に行ったり、気分転換しつつ仕事をしたい時に行く(ワーケーション?)ぐらいの利用頻度が良い感じだと思います。

      (候補4: 熱海のリゾートマンション)

      • メリット: 東京まで通いやすい(新幹線で乗換なしで大手町へ行ける)
      • メリット: 充実した共有設備(温泉・サウナ・プール・フィットネスなど)
      • デメリット: 買えば安いが借りると高い(けど、買うと負動産一直線)

      都心までの通いやすさを考えると、熱海あたりが良さそう。

      熱海には数十年前に流行したリゾートマンションがかなり安く売り出されています。

      ただし、リゾートマンションは共有設備がゴージャス過ぎる関係で固定費(管理費・修繕積立金)が高く、そろそろ築半世紀程度の物件もある関係で大規模修繕リスクもありそうなので、買うのは得策ではないと思います。

      買うのがダメなら借りれば良いのでは?と思って調べてみたら、そこそこお手頃な価格の物件がありました。ただし、東京で暮らすのとあまり変わらない程度の支出になりそうです。物価もそんなに変わらないので、もしかすると東京で暮らす方が支出を抑えられるかも。

      物価については、東京でも足立区・葛飾区あたりなら下手な田舎よりも安いです。実際私の食費は自炊に切り替えてからは珈琲、おやつ、酒などの嗜好品(※タバコ代を除く)込みで、1ヶ月あたり2万円台程度に抑えられました。(田舎だと地元産品でも謎ブランディングをしていて高かったり、競合が居ない or 少ない所だと東京のスーパーよりも高かったりします)

      充実した共有設備の中で生活できる事に価値を感じるなら、一考の余地があるかもしれませんが、私の性格上、マンションの共有設備は行くのが億劫になってほぼ行かなくなりそうなので、支出に見合う頻度の使用ができなさそうだなと...

      「遊びのつもりでとりあえず2〜3年だけ住んでみる」と割り切り、2〜3年後に決心が鈍らないように定期借家物件(契約期間 = だいたい2〜3年経過後に原則契約の更新が出来ない特定期間限定滞在向けの物件)にしてみると良いかもしれません。定期借家物件だと更新できないデメリットの変わりに(グレード比で)賃料が安めだったりします。

      (結論)

      結論は保留(あと半年は様子見したいところ)ですが、やはり実家かなぁ...

      9月11日〜15日に夏休みを取得して帰省、16日〜18日に実家でリモートワーク、19日〜22日の4連休の中頃に東京帰宅というプランを試してみている所ですが、今後半年間、機会を見て何度かこういう実地試験をしてみようと思っています。実家は一軒家なので、テレカンで声を張ることができることに加え、ネット環境も東京の自宅より若干強いので、むしろ東京よりも働きやすいのではないかと予測中。

      仮にこういう感じで地方移転する人がどっさり増えれば、2040年には行き詰まると言われる地方財政も持ち直せるのではないだろうか?地方行政サイドにしてみれば、リターン(経費)が必要なふるさと納税よりもお得な形で税収ゲットできる事になるので。

      2020年8月29日土曜日

      東方VGS(Bach)

       先週ぐらいからVGSのMML打ち込み作業のリハビリ(?)がてら、作りかけだったゴールドベルク変奏曲の続きを作り始めてみました。

      Variation 13 (先週)

      https://github.com/suzukiplan/tohovgs-cli/commit/f3550f245791a0ad5b0a8df26ffaf186e96a72d6

      Variation 14 (今日)

      https://github.com/suzukiplan/tohovgs-cli/commit/c5ceb067c244f7699b46cd58d4d1bb12c3f2d63e

      もうVariation 15に取り掛かってますが、Variation 15は重めのカノンなので結構時間が掛かりそうです。ですが、Variation 30まで週一ペースをキープしたいな...(本業が鬼のように忙しくならなければ多分イケる筈)

      ゴールドベルク変奏曲が終わったら次は何をやろうか。

      今やりたいと思っているのは6つのパルティータ(6つとも)です。

      そのうち東方にも手を出すかもしれません。というか、東方永夜抄の中盤あたりからの曲は色々と病んでいる時に作った関係でかなり手直ししたい部分がある...なので、再び東方に手を出すとしたら作成済みの曲の手直しになるかも。

      何より、新規で耳コピするのはダルいですし(本音)

      耳コピといえば、最近ラブライブの曲をチマチマ耳コピしてます。

      ベースの練習用にベースパートのみですが。(なお、ベースの演奏はかなり下手クソな模様)

      ベースパートの耳コピは音だけで拾おうとするとかなり難しいので、拾いやすいメロディーパートを先に耳コピして、曲の構造を洗い出し、理論から半分推測でベース音を当てはめるという回りくどいやり方でコピーする(東方の耳コピもそんな感じだった)のですが、Logic Pro Xに音源を取り込みイコライザでベースブーストのエフェクトをかければベース音をメロディーと同じように比較的簡単にコピーできることに最近気づきました。

      この技を使えば東方の耳コピも以前よりはだいぶ楽にできるかも。

      2020年8月25日火曜日

      最近のコーヒー事情(自宅&外)

      アイスコーヒーが好きなので、ほぼ年中飲んでます。

      在宅勤務になる前は、主に喫茶店とコンビニコーヒー。

      在宅勤務になってからはUCCの「職人のコーヒー」という930mlペットボトル。ペットボトルは1本78円で買えるのでお財布に優しい反面、洗って潰して捨てるのが中々面倒臭い。フニャフニャのペットボトルなら良いのですが、コーヒーのペットボトルって固いので潰すのが面倒臭い。玄関口に並んでいる「捨て待ち」の空ペットボトルがどんどん溜まっていくのを見ていると憂鬱な気分になります。さてどうしたものかと思っていたところ、近所のヨーカドーで水出しアイスコーヒーポットなるものを発見。

      https://www.monotaro.com/p/4337/4486/

      近所のスーパーで400g 298円の安いコーヒー粉を使って作ってみたのですが、メチャクチャ美味しい。200〜300円ぐらいで飲める喫茶店のアイスコーヒーより断然美味しい。昔、品川駅で待ち合わせをしていた時にウッカリ間違って入ってしまった意識高い系のコーヒー専門店で飲んだアイスコーヒー(1杯800円近くしたブルジョア向けの高級品)と同じぐらい美味しい。1杯800円相当のコーヒーが約4リットルで298円と考えれば激安。

      廃棄についても一般ごみしか出ないので楽です。

      ただし、抽出に時間が掛かる(1回の抽出に8時間掛かる)ので、2本導入してアクティブ・スタンバイのクラスタ構成にする方向で検討中です。

      自宅のコーヒー環境は完璧ですが、問題は外の喫茶店。(在宅勤務に切り替わった影響で全然気づかなかったのですが、いつの間にかタバコが吸えなくなっていた...)

      2020年8月22日土曜日

      エアロバイク導入

       毎週土日に水元公園という近所の公園(23区で一番デカイらしい?)を組み込んだ15km前後のサイクリングコースを周回していました。

      (コース)

      • 水元公園まで: 5〜6km前後
      • 水元公園内: 3kmぐらい
      • 帰宅: 5〜6km前後

      地形を覚えるため、Googleマップなどは使わず物理マップを脳内マッピングしながら進んでいる(なので、かなり高確率で迷う)ので、公園内以外の距離はあまり正確ではないです。多分、片道で10kmぐらい走ることもあります。なお、公園内は人が多いのでインターバル(クールダウン)区間と割り切ってゆっくり安全運転してます。水元公園は、大きな溜池、北海道のような平原、森林などがコンパクトに詰まった走っていてとても気持ちが良い区間だから、ゆっくりと走らなければ損だとも言えます。

      かなり良い運動になります。
      春先は良かったのですが、自粛モードが解除されたぐらいの頃から、色々と懸念が出てきました。
      • 事故が怖い(一応なるべく車通りの少ないコースを選定しているが7月以降は交通量が気持ち多めで怖い)
      • 雨の日はできない
      • 日中は光化学スモッグ注意報がしばしば発令されている
      • 事故回避のため夜間はNG
      • マスクがかなりキツイ(これは運動目的だと高山トレーニングのような効果があるので逆に良いことかもしれない)
      • 水分補給コストの問題(750mlでは全然足りず、汗の量から多分1Lよりも多めに補給する必要があるけど、そんなデカイ水筒は持ってない & 自販機で買うと高い)

      という訳で、秋ぐらいまでは毎週恒例だったサイクリングを暫くお休みすることにしました。

      ただ、在宅勤務で運動不足気味だし、思いっきり運動しないと寝付きが悪いので、さてどうしたものか・・・と、考えていたところ弊社の取締役が「エアロバイクはいいぞ」と勧めてきたのでAmazonでエアロバイクを物色してみたところ、以下のSTEADYという商品が気になったので買ってみました。

      https://www.amazon.co.jp/dp/B07HNVVZ38

      購入を決めたポイント

      • 静音性の評価が高い
      • iPadを見ながら使える
      • サイズ感

      静音性についてはマンションなので必須事項です。幸い私の自宅(4F)は1〜3Fが商業施設(メディカルモール)で隣室が看護師の休憩所っぽいので、音の面はあまり問題ないかもしれませんが、以前リモート会議で喋っていたら隣室で休憩中と思しき看護師から軽く壁ドンされたことがあるので、あまり音が出るヤツは避けたほうが良さそうだなと。

      iPadを見ながら使える事もかなり重要です。昔、ジム通いをしていた時期があるのですが、風景が変わらない状態で走ったり漕いだりするのはとにかく退屈だからすぐに飽きてしまう(なのでジムでは水泳中心でした)ので、iPadでdアニメでも見ながらやれば飽きずに漕げるかなと。

      サイズ感については、折りたたんだ状態ではなく広げた状態のサイズ感を重視しました。折りたたんだり仕舞ったりしてしまうと、出すのが面倒臭くてタンスの肥やしになると考えられるので、ベッドルームに常にセットアップした状態で配置可能な程度のサイズであることが重要です。

      とりあえず、数日使ってみたところ、以下のような使用パターンで定着できそう。

      • 朝、起床後にアニメ1話(約20分)をみながら重さ7の設定で漕ぐ→汗びっしょり
      • 昼ごろは気が向いたらちょくちょく重さ6以下で5分ぐらい走らせる→ストレス解消
      • 夜、風呂前にアニメ1話(約20分)をみながら重さ7の設定で漕ぐ→汗びっしょり

      ちなみに、重さは8段階で最大が8で、7は最大より1個軽い設定です。

      毎日ルーチン的にやれるようにするため、意図的に筋肉がつかないように(筋肉痛にならないように)調整したつもりだったのですが、何か股関節あたりが筋肉痛っぽい感じになってしまったので、もっと軽くした方が良いかもしれません。Amazonのレビューに少し書かれてましたが重めの設定だと負荷バランスがあまり良くはないかもしれません。ただ、軽め(6以下)だとアニメ1話では汗びっしょりにはならないので、プロテインでも飲んだ方が良いかも。

      2020年8月17日月曜日

      東方BGM on VGS(コマンドライン版)

      コマンドラインで動作する東方BGM on VGS(東方VGS)を作ってみました。

      https://github.com/suzukiplan/tohovgs-cli

      今の所、macOSのTerminal専用です。

      Windowsの方がニーズがあるのかもしれませんが、手元に使えるWindowsマシンがない and 今後Windowsを使う予定もないので、どうしてもWindowsで使いたい場合、頑張ってポーティングしてください...(Linuxであれば私のメインマシンがmacOSからLinuxに変わったら対応予定)

      プレイリストを簡単に編集できる形にしておいたので、好きな曲だけ任意回数ループさせたりといった細かいカスタマイズが簡単にできます。

      在宅勤務のお供などにどうぞ。(その目的で自分用に作ったものだったりします)

      2020年8月2日日曜日

      Z80での PUSH/RET について

      Z80エミュレータのテストのために作ったゲームギア・エミュレータのテストの過程で、ゲームのコード解析を結構したのですが、その中で面白かったテクニックとしてPUSH/RETというものがあります。

      PUSH: スタックにデータを格納する命令
      RET: CALL元へ復帰する命令

      RETはCALLから復帰するための命令ですが、戻りアドレスはスタックから取り出すので、「スタックからPOPして得られるアドレス値へジャンプする命令」と解釈することもできます。

      つまり、アドレス値をPUSHしてからRETを呼び出せば、「PUSHしたアドレスにジャンプ」することができます。6502には、任意メモリに格納されたアドレスへジャンプする命令が存在しないので、6502であれば割と有用なテクニックだったといえます。

      ただ、Z80のプログラムでこのテクニックを利用する意味が分からないです...Z80であれば、任意メモリに格納されたアドレスへジャンプする命令(JP (HL) など)が存在するので。

      性能面についても、PUSH/RETを使うメリットはありません。
      そもそも、スタックアクセスが遅いので。

      例えば、アドレス nn に格納されているアドレスにジャンプしたい場合:

      (PUSH/RET)
      LD BC, $(nn) ... 20Hz
      PUSH BC ... 11Hz
      RET ... 10Hz
      合計: 41Hz

      (JP (HL))
      LD HL, $(nn) ... 20Hz
      JP (HL) ... 4Hz
      合計: 24Hz

      上記のように、PUSH/RETだと「17Hz」もの無駄クロックを消費してしまいます。
      PUSH(スタックアクセス)がそもそも重い上に、RETも(スタックアクセスするので)重いので、PUSH/RETでは性能的な意味での恩恵が得られることは無い筈です。

      なのに何故、あのゲームはZ80だと一見無意味なPUSH/RETを使っていたのか...謎が深まります。(プログラマがFCに慣れてて、Z80をあまり知らない状態で書いたとかそんなオチでしょうけど)

      2020年8月1日土曜日

      自前Z80エミュレータのテスト完了

      昨年作成したきり放置気味だった自作Z80エミュレータ(C++)でシステムテストを実施して完成させました。

      システムテストは、別途ゲームギアのエミュレータを作成して実施しました。(なお、作成したゲームギアについては、現在進行系でゲームギア関連ビジネスが動いているようなので、念のため非公開にしておきます...既に完成度が高いエミュレータなら沢山ありますし)

      Z80を搭載したゲーム機なんて沢山あるんじゃないかと思いきや、意外と少なくて、シングルコアで純正Z80を搭載しているのは、調べた限りではSG-1000、Sega MARK III、Sega Master System、Game Gearぐらいのようです。(ゲームボーイがZ80カスタムなので若干惜しい)

      そして、その中で私がハードとソフトを唯一持っているのがGGだったので、GGエミュレータを作ることにしました。なお、GGのハード仕様については、以下の資料を読んで把握。
      セガのハードは中々面白くて、初代SG-1000の中身はだいたいMSXと同じ構造です。
      そして、SM3、SMS、GGはVDP(Video Display Processor)をゲーム向きの専用設計(モード4)に切り替えていますが、ハード構造的にはSG-1000と(ついでに、オセロマルチビジョンとも?)互換性を持たせられる設計になっているようです。

      モード4のVDPはかなりシンプルな構造です。
      16KBのRAM(VRAM)の中にパターンテーブル、ネームテーブル、OAM(Sprite Attribute)がある形。
      ファミコンのハード仕様を理解していれば、容易に理解できると思います。
      ファミコンと違ってネームテーブルがかなり扱いやすくなっていて、キャラクタパターン(1byte)と属性データ(1byte)のセット(2byte)で1セルを表現する形になっています。(ファミコンでゲームを作った事がある人なら分かると思いますが、かなりプログラムし易いメモリレイアウトになっています)

      GGの場合、MSX相当(SG-1000相当)のモード実装は不要っぽかったので、2週間ぐらいで作れました。(途中4連休もあったので楽勝)
      GG Dumperで手持ちのカセットからROMを吸い出して動作検証したところ、手持ちソフトの範囲では10割正常に動きました。(そんなに沢山持ってないのが悔やまれる...)

      【動作確認したソフト】
      ・ベアナックル2
      ・GG忍
      ・ソニック・ザ・ヘッジホッグ2
      ・ドラゴンクリスタル
      ・デビリッシュ
      ・魔導物語1(PSG/PCMでちゃんと喋ります)
      ・魔導物語A
      本体が通電不可能なので、今度ハードオフで見つけたら調達予定...
      (ついでに検証ソフトも増やしたい)

      私の自前Z80の場合、ほぼ実機相当のマシンサイクル単位(実は厳密には少し違うけど...)で同期実装が可能なので、エミュレータ開発者の誰もが苦労する同期実装周りで苦労することはありませんでした。GGの場合、LCDディスプレイ領域は160x144ピクセルですが、内部的には1フレーム342x262ピクセル(NTSC)で処理していて、4Hzにつき3ピクセル描画する形で同期すれば完璧な同期を実現できます。(CPUパワーはかなり消費しますが)

      このテスト過程で発見したZ80側のバグがこのPull Requestでfixされています。

      先日、このZ80エミュレータにゲームボーイのCPU(LR35902)のコンパチブルモードも実装したので、ゲームボーイのエミュレータも作ろうと思えば作れますね。(作るとは言っていない)

      2020年7月30日木曜日

      ブログ のデザイン変更

      ブログのデザイン変更をかなり大幅に変更しました。

      ダークテーマに慣れすぎたせいで、微妙に明るくて見にくかったのでダークテーマのデザインに変更しつつ、そろそろ細かい字を見るのがキツイお年頃なのでフォントサイズなどを大きめにしてみました。

      過去記事で色が見難い箇所があるかもしれません。
      色は基本的にデフォルトから変えるべきではないですね。(今後は気をつけよう)

      2020年7月29日水曜日

      ゲームボーイのCPUについて

      ゲームボーイのCPUについて、誤った技術情報が検索トップの方に表示されるので、私が把握する限りでZ80との仕様差を書いておきます。

      ゲームボーイのCPUとは?
      ☓ 8080
      ☓ Z80
      ○ 8080カスタム or Z80カスタム(正確にはSHARPのLR35902)

      Z80との仕様差:
      1. 1マシンサイクルが全て4Hz(なので全ての命令のTサイクルは4で割り切れる)
      2. 一部フラグ(S, P/V, X, Y)が存在しない(※X, Yはundocumented)
      3. レジスタ IX, IY が存在しない
      4. プレフィクスDD(IX命令)、FD(IY命令)が存在しない
      5. 裏レジスタが存在しない(ので、EX/EXX命令も存在しない)
      6. IN/OUT命令が存在しない(I/Oは$FF00〜$FFFFにメモリマップド)
      7. プレフィクスED命令(結構便利な命令群)が存在しない
        1. $ED $4D (RETI命令) については $D9 (EXX命令) へ移動
        2. Rレジスタに実質アクセスできない(Rレジスタ=DRAMへ通電するためのレジスタで命令実行毎に0〜127の範囲でインクリメントされ続けるもの。この特徴を利用してゲームでは乱数ジェネレータとして利用されることがあるが、ED命令削除の影響でゲームボーイでは利用できないので、乱数を使いたい場合は自前の乱数テーブル等を作る必要がある)
      8. プレフィクスCBのSLL命令(undocumented)がSWAP命令に置き換わっている(SWAPはレジスタ上位4bitと下位4bitを入れ替えるLR35902固有機能)
      9. DJNZ命令がSTOP命令に置き換わっている(STOPはHALTよりも省電力な割込待機機能)
      10. LDI/LDD命令をシンプル化(Bレジスタのデクリメントを行わず、HLのインクリメント・デクリメントのみ行う)
        1. LDIR/LDDR(OTIR/OTDR)相当の命令が無いのでBレジスタのデクリメントが要らない(これらの命令は結構便利だが、継続条件時に5Hzの無駄クロックが発生する関係で、性能が求められる箇所では使用せずにOUTI, OUTI, OUTI...などといった形でRじゃない方の命令を並べて書くのが普通...つまり、ゲーム用CPUなら無くても良いよね という判断だと思います)
      11. LDH命令を追加($FF00〜$FFFFへのアクセス命令のサイクル数を少なくしたもの=I/O命令の代替用)
      12. スタックポインタを便利に使えるようにする命令群(LD (addr),SP / ADD SP,d / LDHL SP,d)を追加(※LDHLはADD SP,dの結果をHLに代入する命令)
      13. LD (addr),A と LD A,(addr) の命令コードを変更
      14. LD HL, (addr) と LD (addr), HL を廃止
      私の認識はだいたいこんな感じ。

      これで本当に正しいか少し自信がないので、自前Z80エミュレータにLR35902コンパチモードを追加して検証してみようと思っているところです。
      https://github.com/suzukiplan/z80/pull/17

      (以下、余談)
      ゲームボーイのCPUが8080派生なのかZ80派生なのかという議論を目にしますが、機能的には8080とZ80のどちらにも近いと思います。レジスタセットは8080に近いし、豊富なシフト命令(CB prefix instruction set)はZ80に近い。また、IN/OUT命令をメモリマップで代用しているから6502っぽさも感じられます。(Z80をよりゲーム用に洗練させた感じなので、GBZ80という通称が一番しっくりくる)
      敢えて、8080派生 or Z80派生のどちらが正しいかを「CPUの設計過程でどちらをベースCPUにしていたか」という観点で推測すると、Z80派生が正しいと思います。というのも8080をLR35902化するのと、Z80をLR35902化するのなら後者の方が設計コストが圧倒的に低いので。(8080派生だとするとCBプレフィクス命令の追加設計が物量的に重そうだし、bit/set/res命令辺りは普通にand/orで代用できてand/or比で性能的なメリットも無いから、ゲーム用の機能としてわざわざ新設する意味がないような気がするので)

      2020年6月1日月曜日

      AWS + Docker + Redmine の簡単な構築手順(pluginを使いたい場合)

      AWS/EC2(Amazon Linux 2)でDockerを使ってRedmineの環境構築をした際のメモです。公式のredmineのDockerイメージを使い、尚且プラグインを使いたい場合、多分これが一番簡単だと思います。

      (0) スワップ領域確保

      EC2の弱いサーバ(t2.micro)で動かす場合、redmineを動かすと割とカジュアルに「メモリ不足」で落ちます。スワップ領域を1GBほど確保すれば、t2.microでも問題なく動きます。(t2.microのお値段は30日あたり$4.176)

      dd if=/dev/zero of=/tmp/swap.img bs=1M count=1024

      chmod 600 /tmp/swap.img

      mkswap /tmp/swap.img

      swapon /tmp/swap.img

      free


      (1) docker / docker-composeをインストール

      sudo yum install -y docker
      sudo systemctl enable docker
      sudo systemctl start docker

      sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      sudo chmod +x /usr/local/bin/docker-compose

      (2) redmineのDockerfileを作成

      sudo mkdir ~/redmine
      sudo mkdir ~/redmine/work
      sudo mkdir ~/redmine/redmine
      sudo vi ~/redmine/redmine/Dockerfile

      以下、Dockerfileの内容:
      FROM redmine:4.1-passenger
      RUN apt-get update && apt-get install build-essential
      WORKDIR /home/ec2-user/redmine/work
      RUN bundle install
      RUN rake redmine:plugins:migrate RAILS_ENV=production

      メモ: 当初docker-compose.ymlだけで「image: redmine:4.1-passenger」を指定して構築したのですが、それだとプラグインをビルド(bundle install)時に「make not found」でビルド失敗してしまいます。公式dockerイメージにはbuild-essentialが入っていないので、公式dockerイメージは(そのままでは)pluginを導入することができません。なので、redmine用のDockerfileを個別に作成して、RUNスクリプトでbuild-essentialをインストールしつつ、ついでにbundle install + DBマイグレーションを実行しておくことが必須です...
      今どきredmineを使う所も稀かもしれないけど、その中でもpluginを使わない人なんて居るのだろうか?なので、(Dockerポリスからは怒られるかもしれないが)公式のdockerイメージにbuild-essentialを入れておくべきではなかろうか。

      (3) docker-compose.ymlを作成

      sudo mkdir /var/lib/redmine
      sudo mkdir /var/lib/redmine/config
      sudo touch /var/lib/redmine/config/configuration.yml
      sudo vi ~/redmine/docker-compose.yml

      以下、docker-compose.ymlの内容:
      version: '3.5'

      services:
        redmine:
          build: ./redmine
          container_name: redmine
          ports:
            - 3000:3000
          environment:
            TZ: Asia/Tokyo
            REDMINE_DB_MYSQL: mysql
            REDMINE_DB_DATABASE: redmine
            REDMINE_DB_USERNAME: redmine
            REDMINE_DB_PASSWORD: redmine
            REDMINE_DB_ENCODING: utf8
          depends_on:
            - mysql
          restart: always
          volumes:
            - /var/lib/redmine/files:/usr/src/redmine/files
            - /var/lib/redmine/log:/usr/src/redmine/log
            - /var/lib/redmine/plugins:/usr/src/redmine/plugins
            - /var/lib/redmine/public/themes:/usr/src/redmine/public/themes
            - /var/lib/redmine/config/configuration.yml:/usr/src/redmine/config/configuration.yml

        mysql:
           image: mysql:5.7
           container_name: mysql
           restart: always
           environment:
             TZ: Asia/Tokyo
             MYSQL_ROOT_PASSWORD: devops
             MYSQL_DATABASE: redmine
             MYSQL_USER: redmine
             MYSQL_PASSWORD: redmine
           volumes:
             - mysql-data:/var/lib/redmine/mysql
           command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci

      volumes:
        mysql-data:
          name: mysql-redmine

      (4) プラグインの追加方法

      1. /var/lib/redmine/plugins以下にgit cloneなりコピーなりして配置
      2. docker-compose restart
      起動が上手く行かない場合、ログを見るなりdocker-compose upとかで起動するなりして失敗原因を確認。多分、何かしらのサードパーティーツールが足りていない筈なので、必要なやつをDockerfileのapt-get installに追加してイメージ再作成すればOK。(build-essentialだけあればほぼ問題無いと思いますが念の為)

      (5) メール配信をしたい場合

      1. /var/lib/redmine/config/configuration.yml に必要な設定を追加
      2. docker-compose restart
      SESを使う場合はこんな感じ:
      production:
        email_delivery:
          delivery_method: :smtp
          smtp_settings:
            address: "SMTP settingsに書かれているホスト名"
            port: 587
            domain: "ドメイン(※ドメイン認証は無くても大丈夫かも)"
            user_name: "取得したSMTPクレデンシャルのユーザ名"
            password: "取得したSMTPクレデンシャルのパスワード"

      (6) Redmineのバージョンを変更したい場合

      DockerfileのFROMを修正した後、

      docker-compose stop
      docker-compose up -d

      とかでイケるはず。

      (7) クラウド環境で動かしたりとか

      ここまでで記載した内容でとりあえずオンプレミスでは正常に動きます。
      クラウド環境というかインターネット上で動かす場合に必要な設定を記載しておきます。
      • Route53やお名前.comなどで独自ドメインを確保
      • ACM(Certification Manager)で、確保したドメイン(ex: example.com) or そのサブドメイン(ex: redmine.example.com)の証明書を作成
      • ELB(ロードバランサ)を作成(リスナーはhttps※ポート番号はウェルノウンポートを避ける、ターゲットは作成したインスタンスのhttpポート3000/tcpへオーバロード & ACMで作成した証明を割り当て)
      • Route53の確保したドメインのホストゾーンにCNAMEレコード追加してELBのホスト名に繋ぐようにする(Elastic IPを割り当てているのであればAレコードでもOKだけどElastic IPは有限なのでCNAMEの方が多分都合が良い筈)
      • Redmine自体の設定でユーザ作成は無効化(管理者が対応)、認証を必須、パスワードログインは基本的にせず自社のGsuiteアカウントを使ってGoogleアカウント認証(それができるプラグインがあり自社ドメインに限定等が出来る)でログインして貰うようにする。
      • adminの無効化方法は分からなかった(私はRedmineにはまだ詳しくない)ので、とりあえずクソ長くて解読しにくいパスワードにして対処
      上記のような感じで設定すれば、多分、セキュリティレベルとしては普通のクラウド版Redmineサービス(MyRedmineとか)よりも高い筈。

      月額コストはだいたい850円〜900円ぐらい。
      ※とりあえず、EC2はt2.microでEBSに全部載せという雑な構成で動かす場合
      ※EC2の無料分に収まれば多分月50円(データ転送やSESのコスト分のみ)ぐらいかな(使用頻度による...)
      多分、クラウドサービス版RedmineではMyRedmineが一番安い筈ですが、それでも月8,000円掛かります。Redmine自体割と枯れたシステム(※褒め言葉)なので、社内運用とかであれば保守の人員コストもそんなに掛からないことを勘案すると、自社で構築してしまった方が多分コスパが良いです。((1)〜(7)までの構築に掛かる人件費ですが、AWSに慣れた人なら0.5人日以下でサクッとできてしまいます)
      自社で何らかのWebサービスを構築する or 運用しているのであれば、その練習台(インフラエンジニアの新人研修ネタ?)としても丁度良いかも。DBをAurora、EBSに乗せているfilesディレクトリ(添付ファイルデータ)をEFSに変えればAutoScalingを用いてスケールアウトさせることも出来るので、スケーラビリティ設計の練習台にもできそう。

      リモートワーク(テレワーク)対応で、今までオンプレで使っていたRedmineをクラウドサービスに移行しようとして、MyRedmineを使う予算承認が降りたのですが、MyRedmineを試食してみたところ「これなら自分で作った方が早いし安い」と思い自前構築した時のメモでした。(今更Redmine...と思いつつ、こういうケースって多いかも?)

      実のところ、構築するのが面倒だった(0.5人日で済むとはいえ一応工数が掛かる)のでMyRedmineで良いじゃん(安いし)と思っていたのですが、MyRedmineの場合、契約書に決済者(※私は決済者ではない)の手書きサイン or 会社名が入った社印が必要とのことだった(※要するにWeb申し込みで完結しない契約タイプだった)ので、いわゆる「ハンコ打ちに会社行かなければいけないヤツ」だったことが自前構築の決断要因でした。
      会社に行くと往復2時間(0.25人日)無駄にするし、決済者を捕まえるためのスケジュール調整にも無駄に工数が掛かるので、0.5人日掛けて自前構築した方がお得な筈。

      2020年5月14日木曜日

      電子マネー

      政府からの特別給付の手続きで、せっかく電子証明書付きのマイナンバーカードを持っているものの、スマホ(旧型iPhoneSE)がNFC非対応だったので新型iPhoneSEに買い替えました。

      申請自体それで滞りなく行えたので良かったのですが(...ただし、現状のマイナンバー制度は色々と不備が多く市区町村の行政サイドが色々混乱しているらしいので、実は郵送申請にした方が良かったのかもしれませんが)、それよりもApplePayが予想以上に便利だったので端末を買い替えて良かったなと。

      今まで電子マネーは主にVIEW Suicaを使っていて、チャージ手段はオートチャージでした。ところが、2月末からリモートワークになり改札を通る機会が激減。電車に乗る機会は、月に1回あれば良い方(3月=0回、4月=1回、5月=今の所0回)になり、その結果オートチャージができず、仕方なく券売機で現金チャージをするという「電子マネーとは?」という状態でした。

      現金は、調達するのにATM手数料が掛かるので極力使いたくないです。
      なので私は、現金しか使えない店は原則使いません。
      ついでに今なら、現金(特に硬貨)は衛生面の関係で触ることが憚れますし。

      新型iPhoneSEを導入したことでApplePayが使えるようになったので、メイン電子マネーをモバイルSuicaに切り替え、VIEW Suica(クレジットカード)からチャージする運用に変更することにしました。

      ApplePayなら、何処で幾ら使ったがひと目で分かるので、支出管理も大分楽になります。
      また、スリープ状態でも決済できるのでQR決済(スマホ決済)よりも使い勝手が良いです。

      QR決済については、近所のスーパーが電子マネーはPayPay(QR決済)しか利用できない関係でとりあえずPayPayも使ってますが、やはり決済の都度アプリを起動するのは面倒臭い。

      多分、QR決済は(Origamiの実質破綻などがありましたが)NFC対応デバイスが普及するまでの過渡的な存在だと思うので、将来的には(NFC対応デバイスが普及しきったら)無くなると思っています。

      恐らく、将来的にはPayPayは生き残るためにやむを得ずQRを捨ててNFCなりFeliCaなりになると思いますが、そうなると私ならSuicaに切り替えてPayPayは捨てますね。
      Expressカードはひとつしか選べないので。

      2020年5月11日月曜日

      CPU dummy read (MOS6502)

      GW中にMOS6502のエミュレータを作ったのですが、
      https://github.com/suzukiplan/M6502
      そのテストをするためにファミコンエミュレータを開発中です。
      https://github.com/suzukiplan/OpenNES

      NesDev Wikiで公開されているテストコードを全部通すことが当面の目標。
      https://wiki.nesdev.com/w/index.php/Emulator_tests

      とりあえず、branch_timing_testsは無事全部通りました。



      この勢いで、cpu_dummy_readsも通そうとしたのですが、失敗...

      CPU Dummy Readsってそもそも何?と思い、スレッドを確認。
      https://forums.nesdev.com/viewtopic.php?p=31629

      absolute X、indirect Yでページがクロスオーバーするとpenalty clockが発生するのですが、その時、

      ldx #$22 lda $20E0,x ; dummy read from $2002 ldx #$22 lda $20E2,x ; dummy read from $2004 ldx #$22 lda $3FE0,x ; dummy read from $3F02

      という感じでdummy readが発生するらしい。

      という訳で対策
      https://github.com/suzukiplan/M6502/commit/ff19b729a7132554ea4be5a714ca894fade489d2

      absolute Yの時についてはスレッドで言及されていなかったのですが、一応absolute Yの時にもdummy readする感じにしてみました。(これが正しいかは不明)

      2020年4月10日金曜日

      Sign in with Apple対応メモ

      サードパーティー製のログイン機能を実装しているiOSアプリが、Sign in with Appleに対応していないと審査でリジェクトされるようになった(リジェクトされた)ので、マッハ(1.5日ほど)で対応した時の要点メモを残しておきます。

      【要点】
      以下、C = クライアントサイド & S = サーバサイド です。

      • C: ASAuthorizationAppleIDButtonでSign in with Appleボタンを設置
      • C: ASAuthorizationControllerで認証UIを呼び出す
      • C: ASAuthorizationController.delegateで認証結果を受け取る
      • C: 認証コード(ASAuthorizationAppleIDCredential.authorizationCode)をサーバへ送信
      • S: apple-authへ受け取った認証コードを渡し、Appleのサーバからsub等を取得(こんな感じ)して自サービスのアカウントの紐付けとかをする

      【サーバサイド】
      • サードパーティー製ライブラリを使うほどのものでもない対応内容ですが、急いでいたし、apple-authの説明が分かりやすかったので採用(感謝)
      • ハマり所は特に無し(例によってApple Developerでの諸々の設定が面倒で、provisioning profileの更新周りで小一時間手間取る程度)
      【クライアントサイド】
      • 特にUI(導線設計)周りは指示通りにやらないとリジェクト・リスクがあるので注意した(なんやかんやでこれが一番対応コストが掛かる。デザイナとSlackで半日程度やりとりしてザックリと決めて即日実装)
      • 唯一のハマり所は、ASAuthorizationAppleIDCredential.authorizationCodeがNSData型だったので「Base64にするん?」と勝手に想像して実装したことぐらい。単純にこれはUTF8のconst char*型データなので以下のようにすれば良い。
      ```objective-c
      NSString* codeText = [[NSString alloc] initWithData:code encoding:NSUTF8StringEncoding];
      ```

      【雑感】
      • タッチIDで認証できるのは中々快適
      • landscape専用のアプリだが、認証画面がportrait専用(iPhoneの場合)
        • 多分、フェースID絡みの関係で、縦にせざるを得なかったのではないかと想像(やっぱり、タッチIDこそが至高)

      2020年3月29日日曜日

      GitLab社によるリモートワーク虎の巻(概略解説)

      67か国に1,200人以上もの従業員を抱えるオール・リモートワーク企業のGitLab社が、リモートワーク導入のためのPLAYBOOKを公開していることがIT MediaGigazineなどで紹介されました。ただし、それらの記事でPLAYBOOKの全体的な内容については、ざっくりとしか説明されていないようです。

      PLAYBOOKは以下URLから無料でダウンロードできるので、各々が内容を確認すれば良いとは思いますが、如何せん全部英語で書かれているので、読むのが結構大変ではないかと思います。全部翻訳しても良かったのですが、英語の方がしっかりコンテキストが伝わります。私はこういったテキストを読む時(正確には読んだ後)、全体を俯瞰的な視点で記した要約書みたいなもの(読書感想文を論理的にインデクス化したもの)を作るのですが、その要約書を記しておこうと思います。幸い、3章以降はオリジナルのPLAYBOOKの方にその要約書に相当する解説が載っているので、結構楽に作ることができました。
      https://about.gitlab.com/company/culture/all-remote/


      PLAYBOOKは、以下の6章で構成されています。
      そして、3章以降(実践編)では章末に「何をすべき」で「何をすべきでないか」が簡潔に纏められています。
      1. 仕事の未来に備える
      2. 企業のリモート対応段階
      3. リモートワークの基礎
      4. 移行を実現する
      5. リモートコミュニケーション戦略
      6. リモート企業文化の確立

      1章では、リモートワークを採用した企業の従業員がすべきことを管理職向けと一般職向けで分けて記載しています。

      (管理職がすべきこと)
      1. リモートリーダーシップチームの設立
      2. ハンドブックを確立
      3. コミュニケーション計画策定
      4. ツールスタックの最小化
      5. 変化を促す
      (一般職がすべきこと)
      1. 集中できる専用のワークスペースを作る
      2. 生活と仕事を分離する
      3. 孤独を避け人々との関わりを絶たない
      4. ルーチンを尊重しつつ変化を試みる
      5. 変化に順応する


      2章ではリモートワーク対応の組織論について解説しています。
      GitLabによると、リモートワーク対応の組織には以下の5つの段階があり、自社が現在どの段階にあるのかを把握すべきだとしています。(それぞれの段階の細かい説明は省略しますので、気になったらオリジナルのPLAYBOOKで確認してください)
      1. リモート非対応
      2. 一時的なリモート許可
      3. リモート併用(リモートと非リモートのハイブリッド)
      4. ひとつのタイムゾーンを基準としたリモート
      5. 複数のタイムゾーンを跨ぐオールリモート
      恐らく、今回のCOVID-19関連の騒動でリモートを導入した企業の大半は段階2 or 段階3止まりだと思われます。また、騒動長期化が現時点で懸念されていることから、段階2の企業も段階3へ移行する可能性がありそうです。ただし、特に段階3に関しては多くのデメリットがある点を指摘している点が興味深いので、(やや長くなってしまいますが)そのデメリットをGoogle翻訳で翻訳したものを以下に記します。

      (段階3のデメリット)
      • ハイブリッドリモートの従業員は、情報へのアクセスが少ない場合があります。 あなたがすべてを文書化する雇用主のために働いていない限り、あなたは、直接の同僚と比較してより少ないか不完全な情報であなたの日常の仕事を処理するように求められるかもしれません。 時間が経つにつれて、これは間違い、混乱、フラストレーション、さらにはパフォーマンスの低下につながる可能性があります。
      • キャリアと開発の機会の減少。 視界の外にあるハイブリッドリモートの従業員は、昇給、昇格、および開発の機会のために引き渡される場合があります。 また、組織内で水平に移動する機会が少なくなり、進化するビジネスニーズに対応するための新しい役割を作成するための影響力も少なくなります。
      • サテライトオフィスのような感覚。 ハイブリッドリモートの従業員は、会社の他のメンバーから孤立していると感じる場合があります。 面接プロセス中に、リモートの同僚がどのようにオンボーディングされ、含まれ、他の人に知覚されているかを尋ねることは重要です。 一部の従業員はこの治療法に気を取られないかもしれませんが、他の人に精神的および感情的な犠牲を払う可能性があります。
      • 罪悪感を管理する。 主に同じ場所に配置されている会社で働いているリモートワーカーが罪悪感を表明するのを聞くことは珍しくありません。 彼らの社会化には、通勤について不平を言うかもしれない、または家族の機能に参加できないために悲しみを表すかもしれない同僚が含まれます。 リモートの従業員は同じ柔軟性に耐える必要がないにもかかわらず、同僚と共感する必要があるため、この取り決めには不平等があります。
      • リモートのロビー活動の負担。 従業員が遠隔地で雇われているが、この配置がチームとマネージャー全体で等しくサポートされていない場合、遠隔地の従業員が物理的なオフィスに通勤することを強制されないという認識された特権を絶えず正当化している状況が発生する可能性があります。
      • リモートが本当に提供およびサポートされているかどうかを判断します。 多くの大企業はリモートの従業員を容認しますが、リモートとして役割を公に宣伝したり、リモートでの作業をサポートしていることを公に認めたりすることはありません。 これにより、ロールを検索するときに、そのような組織内のリモートフレンドリーなマネージャーやチームを検索することに加えて、かくれんぼという面倒なゲームが作成されます。
      • 例にされるリスク。 主に同じ場所に配置された会社の遠隔地の従業員が「では、どうやって遠隔地の手配を手伝ったのですか?」のような質問をされる可能性があります。 これにより、遠隔地の従業員は困難な状況に置かれます。 彼らは、さらに多くの同僚がリモートで作業できるように権限を与え、評判を損なう可能性のある原因を擁護することを選択するか、知覚された特典を自分自身に保つことによって役に立たないように見えます。
      • パフォーマンスの向上に対する要求。 毎日長い通勤時間を過ごす同僚と働いているリモートの従業員である場合、対面のチームメンバーが期待する以上の結果を提供するというプレッシャーに直面する場合があります。 これは、同じ場所にいる従業員が柔軟性に欠けて通勤する必要がある場合、離れた同僚が簡単に降りられないように追加の結果を生成する必要があると推測する羨望の有毒な文化に由来します。
      これらの知見は、GitLab社は元々オールリモートではなくハイブリッドで運用していた時期があり、その際に得られたものだと思われます。リモートを導入する企業は、段階3は過渡的な処置として、基本的に段階4以降への移行が望ましいと解釈できます。

      (補足)
      段階4(グローバル企業なら段階5)に移行できればオフィスをバーチャルオフィス(実体の無い登記専用のオフィス)にしても問題無くなるメリットがあります。例えば、従業員を1,000人抱える大企業であれば通常約3,000坪程度のオフィスが必要ですが、現在の東京都の3,000坪規模で借りられるオフィス(Aクラスビル)の賃料は坪単価3〜5万円/月ぐらい掛かるので、年間10.8億〜18億円程度の固定費削減を見込めます。これはやらない手は無いと思います。ただし、東京のオフィスは不足気味(先月段階で空室率1%を割っていた筈)なので、一度決断すると後戻りできなくなるリスクが想定されます。そのため、中々決断に踏み切ることができない企業が多くあるかもしれません。個人的にはこれを機に郊外にオフィスを移してしまうのも手だと思われるので、思い切ってやった者勝ちだと思います。経営者の決断力が問われます。


      3章(リモートワークの基礎)

      この章では、全てを文書化することとそれが適切に共有されることの必要性を指摘しています。これは、リモート対応か否かに限らず、全ての企業に必要なことです。GitLab社の場合、ハンドブックと呼ばれる仕組みで文書を蓄積&共有しているようです。GitLab社のハンドブックについては、日本語の記事であればコチラの記事で分かりやすく紹介されています。

      (要点)
      1. 信頼を確立するには、非公式のコミュニケーションと社会的つながりを促進することが重要
      2. すべてを文書化し、会社のコミュニケーションに「ハンドブックファースト」のアプローチを採用
      3. 会議をオプションにして、すべての会議に議題を用意し、勤勉なメモを取り、不在の出席者の会議を記録するように要求
      4. 会社の価値観を体系化し、遠隔地の作業環境をサポート
      (行うべきこと)
      • 社会的相互作用を奨励
      • すべてを文書化
      • 必要に応じて会議を開く
      (行うべきでないこと)
      • 相互作用を仕事関連のトピックに制限
      • 1:1の情報伝達に依存
      • 会議を必須にする


      4章(移行を実現する

      今回の防疫対応でリモートを導入してみたものの、結構大多数の企業が何かしら上手く行かないケースに直面しているものと思われます。GitLab社によるとリモートへの移行を実現するための鍵は「文書化」と「ワークスペースの確保」にあるとしており、本章ではその具体的な手段について(例えば、リモートのデスクやチェアはどういう風に設置すべきかなど、かなり細々と)言及しています。「リモートでやってみたけど上手くいかない」と感じられたら、この章の内容を実践してみると良いかもしれません。

      (要点)
      1. 現実には、すべての企業がすでに何らかの形で離れています。 物理的な空間で何らかの相互作用が発生した場合でも、リモートファーストの手法を採用します。
      2. 人間工学に基づいた効率的な作業スペースを作成するように注意してください。 最適な作業環境は、人によって異なります。
      3. 文書化は全員の責任です。 質問して答えを受け取ったら、それを書き留めてください。
      (行うべきこと)
      • リモートファーストの考え方を採用
      • ワークスペースに集中
      • 質問に対する回答を文書化する
      (行うべきでないこと)
      • 社内環境の再現を試みること
      • 答えを得るために仮想の肩を叩く



      5章(リモートコミュニケーション戦略)

      リモートワークを導入する上での最大の障壁は、やはりコミュニケーションの壁であることは既に多くの方が痛感されているかもしれません。本章では、リモートでのコミュニケーションを成功させるための戦略について解説していますが、PLAYBOOKの中で最も多くのページを割いて解説しているので、その重要性を窺い知ることができます。要点としては、文書によるコミュニケーションを基本とした上で、文書によるコミュニケーションを成功させるため手段(低コンテキスト化、絵文字の多用、ツール標準化)について解説されています。
      (要点)
      1. 文書化は日常の仕事です
      2. 低コンテキストの文化を実装して、コミュニケーションが簡潔で直接的になるようにします
      3. 絵文字を多用して、より包括的な環境を育てます
      4. コミュニケーションツールを標準化し、コミュニケーションの分裂を防ぐために使用します
      (行うべきこと)
      • ディスカッションを記録し、トランスクリプトを取得
      • 積極的な意図を想定
      • コミュニケーション過剰であることを恒常化
      • 統合コミュニケーションツールの標準を設定
      (行うべきでないこと)
      • 会議などの同期コミュニケーションに依存する
      • チームのメンバーがすべての事実を持っていると仮定する
      • チームメンバーに対応するよう圧力をかける
      • 時間に敏感ではない質問または完了したタスク



      6章(リモート企業文化の確立)

      最後にどのような企業文化にすべきかという点について言及しています。例えば、非リモートの職場環境では、毎日遅刻せず、朝掃除をし、真面目に仕事をし(あるいはしているフリをし)、上司のおべんちゃらに体よく付き合う社員がそこそこ出世するケースがあります。それも一種の企業文化なので否定するつもりはありませんが、そこに合理性を感じることができません。そのような価値の無い価値観に固執していると、大きな環境の変化が起こった時に淘汰されることになります。そういった時流の変化に対応する上で重要なのが柔軟な企業文化の確立だと私は考えています。この章に記されている内容は、GitLab社がどのような企業文化にすることでオールリモートという大きな変化に耐え得る組織となるに至ったかを示す臨床実験の経過報告だと解釈しています。
      要点としては、(1)フィードバックの確立(2)不文律の排除、(3)従業員のBurnout(燃え尽き症候群、鬱)回避の3点で、それを実現する鍵はやはり「文書化の文化」がその根幹にあるようです。
      文書化することでアウトプットをベースとしたフィードバック確立と不文律の排除が容易になります。
      もう1点留意しなければならないのが「働きすぎ」です。リモートだと始発や終電といった強制的なタイムリミットの成約が無くなることで、真面目な人や優秀な人ほど無制限に働きすぎる恐れがあるため、非リモート以上にその点に気をつける必要がありそうです。

      (要点)
      1. あなたが報酬を与えるどんな行動もあなたの価値になる(フィードバックを提供する際に一貫してそれらを参照することにより、企業価値に対する信念と尊敬を構築)
      2. 遠隔地の文化では、不文律は存在しない
      3. メンタルヘルスを優先し、メンタルヘルスのリソースに簡単にアクセスできるようにする
      4. 休憩をスケジュールし、仕事以外のトピックについて同僚と交流する時間を毎週作る
      (行うべきこと)
      • メンタルヘルスの維持に積極的に取り組む
      • 必要に応じてストレスを解消したり取り外したりするために実行できるアクションのリストを作成
      • ビデオ通話を活用して、仕事に関係のないトピックについて同僚とコミュニケーション
      • デスクから離れているときに他の人に警告するステータスを設定するか、離れている間カレンダーをブロック
      (行うべきでないこと)
      • 1日中オンラインでいなければならない
      • 起きたらすぐに仕事をする
      • 解釈のために詳細を残す
      • 24時間年中無休でコンピューターに接続
      • 愛する人との境界を設定することを恐れなければならない

      2020年3月21日土曜日

      自炊ミスティカ

      前回、最後に自炊したのは確かアテネオリンピック(2004年)がやっていた頃の筈だから、かれこれ16年前の話になります。リモートワークに切り替わって最初にやろうと思っていたことが、食事を外食から自炊に切り替えることです。これは、生活サイクル乱れ防止作戦の一環です。この作戦の主な目的は、通勤に往復1時間費やしていた時間的コストを料理時間に代替することですが、もしかすると美味しく健康的なご飯を頂ける可能性もわんちゃんあるかもしれません(※この辺は料理スキル依存)。銀座在住時は自宅調理場が狭すぎたけど、今の住居には無駄に拾いキッチンスペースがあって、そこをカプメンを沸かすだけのデッドスペースにするのは勿体ないという動機もあります。

      しかし、機材を揃えるのが億劫で中々スタートに至りませんでした。昨日ようやく最小限の機材(仰々しく言ってますがフライパンと食器)と材料の調達ができたので、今朝の朝食から自炊を始めてみました。

      記念すべき1作目はこちら。
      題名: 3月21日の朝食
      (少量の赤ワインとパンで頂く)
      なんか、思っていたのと違う。
      もう少し瑞々しい感じになる筈だったのですが、ザ・男飯になりました。

      目玉焼きが潰れているのは、ヘラみたいなヤツを持っていないから箸でフライパンから出したため。ヘラみたいなヤツはやっぱり必要です。後で100円ショップで買っておこう。

      野菜の焼き加減をかなりミスりました。焦げてはないが美しくもない。目玉焼きを焼いた後のフライパンで、ウィンナーと野菜炒めを作ったのですが、ウィンナーにいい感じの焼き色をつけようとした結果、野菜に火が入りすぎたのが敗因。最初にウィンナーを焼き、良きタイミングで野菜を投入し、いい感じに萎えたらすぐに出すという手順にすると良さそう。

      ちなみに野菜を切る道具を持っていないので、野菜はカット済みのヤツです。70〜100円ほどで1袋買えて、1袋で2食分ぐらいの分量が入っています。本当はキャベツが入っているヤツが良かったのですが、昨夜未明に買いに行った所売り切れていたので、今回はニラとモヤシのみのヤツにしました。(それすら無かったらモヤシオンリー)

      味は普通に美味しかったでうs。

      ちなみに、主食は当面パンになります。
      日本人なら米という若干ステレオタイプ気味な主張に対しての異論はあまりないのですが、残念ながら米を炊くマシンを持っていません。料理に飽きて外食生活に戻す可能性を勘案すると、設備投資タイミングとしては時期尚早です。何より炊くのと片付けが面倒くさい。長く続けるには、片付けの簡略化がかなり重要です。だから、食器はシングルプレート縛りにするつもり。

      レンチンできる米(サトウのごはん)という選択肢ならあり得ますが、レンチン米はコスト面にやや難があります。1食米だけで150円もします。パンなら1食あたり20〜30円ぐらいで十分お腹いっぱいにはならないけど、ワインを混ぜることで血糖値が上がり満腹感らしきものを偽装できます。もちろん、酔うほどの量ではなく、お猪口一杯分ぐらい。

      (材料コスト)
      ・主食(パン+ワイン): 50円分ぐらい
      ・野菜: 50円ぐらい
      ・ウインナー: 50円ぐらい(2袋200円を1Q使用)
      ・卵: 20円ぐらい
      ・各種調味料やサラダ油等: 5円以下
      合計: 175円ぐらい

      (労働コスト)
      ・調理時間: 10〜15分ぐらい
      ・後片付け: 5分ぐらい(フライパン、皿、ワイン用ベネチアングラス、箸)
      合計: 20分ぐらい(時給1200円換算で400円...久々なのでやや手際が悪い)

      野菜は、原材料を自前カットすれば20〜30円ぐらいに落とせるけど、カットする労力(それだけで+10分程度調理コストが掛かる)を考えるとカット済みのヤツを使う方がコスパが確実に優れています。+10分の調理コストが20〜30円で買えるなら十分安いです。自炊を始めた頃は材料コストだけ気にしてしまいがちですが(実際16年前はそうでした)、労働コストを気にすることが重要で、+10分というのは短いようでいて長いというか面倒くさい(片付けの際の洗い物数量が増えるのもダルい)です。+10分で200円の材料コスト圧縮が可能なら一考の余地があります。目安として時給コストを1時間あたり1200円と考えて、その上で「総コスト1食500円以下」などの目標設定をすると良いです。(熟練度が上がればカット+片付けに1分=20円とかにも出来るので、それぐらい熟練度が高ければカット済み素材を使うよりも自前でカットした方が安い)

      包丁等のカット器具への設備投資(初期投資)が要らないのもデカイ。ちなみに、調理器具は蓋付きの安い(1500円ぐらいの)フライパンだけイトーヨーカドーで買い、その他の細々したものは全部100円ショップです。過去の経験則ですが、必要だと思うものを全部そろえてしまうと、かなりの分量の不稼働設備が発生するので、設備は最小スペックで始め、必要なモノを都度買い足すのが良いです。

      合理的ではないものを作りたい

      ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...