子ども向けのタイマーに、カウントダウンを付けませんでした
お手伝いの所要時間を測る機能を作りました。次の段階として予定していたのが「集中モードの全画面表示とカウントダウン」です。全画面は作りました。カウントダウンは、実装せずに機能ごと外しました。技術的に難しかったからではありません。作ると、この機能の目的そのものを壊すと判断したからです。個人開発で「作らない」を選んだ話を書きます。
予定していた機能を、直前で外した
RingiQuest には、お手伝い(アプリの中では「クエスト」と呼んでいます)に「はじめる」を押して所要時間を記録する機能があります。この機能は段階を分けて作っていて、第1段階が「開始と計測」、第2段階が「集中モードの全画面表示とカウントダウン表示」でした。バックログにもそう書いてありました。
第2段階の実装に入る直前、カウントダウンの部分だけを外しました。残り時間の表示、進捗バー、想定時間との比較、超過したときの色の変化や警告——このあたりを全部やめました。
外した理由は工数ではありません。むしろ実装としては簡単な部類です。想定時間から経過時間を引いて表示するだけですから、半日もかかりません。
懸念は、最初から書いてあった
実は第1段階を作った時点で、設計メモに懸念として書き残してありました。「カウントダウンを足すときは、期限切れのペナルティポイントと絶対に連動させないこと」と。
第2段階に着手する段になって読み返したとき、この懸念は「連動させなければ大丈夫」という話ではないことに気づきました。実装上どこにもつながっていなくても、子どもの目には同じものに見えるからです。ここが判断の分かれ目でした。
カウントダウンが、子どもに何をするか
「のこり 3分」と画面に出ているとします。開発者としては、これは単なる情報表示です。実装上は何とも連動していません。数字が0になっても何も起きず、ポイントも減りません。
でも、その画面を見ている小学生にとって、それは情報ではありません。締め切りです。
「間に合わないと、何か悪いことが起きる」に見える
RingiQuest には、期限を過ぎたクエストからポイントを自動的に減らすペナルティの機能があります(使うかどうかは家庭ごとに選べます)。この機能を使っている家庭の子どもは、すでに「時間切れ=減点」という結びつきを学習しています。
その子が、別の画面で数字が減っていくのを見たとき、実装がつながっているかどうかは何の関係もありません。体験としては、同じ種類のものに見えます。「何も起きないよ」と説明しても、0になる瞬間の緊張はなくなりません。
急かしは、雑に終わらせる動機を作る
残り時間が減っていくとき、人がとる行動は2つです。急ぐか、あきらめるか。どちらも、お手伝いの品質にとってはよくない方向です。
「のこり1分」で焦った子が、床の拭き残しを見なかったことにする。これは十分ありえます。そして親がそれを指摘すれば、今度は「急がされた上に怒られた」という体験になる。誰も得をしません。
「時間内に終わらせた」ことへの、逆のごほうび
さらに厄介なのがこれです。カウントダウンがあると、子どもは自然に「時間内に終わらせること」を目標にします。ところがこのアプリで測っている時間は、速さを競うためのものではなく、その仕事が実際に何分かかるのかを知るためのものです。
つまり、時間内に終わらせようとがんばるほど、記録される数字は「その子が急いだときの時間」に寄っていきます。これは、想定時間を見直すための材料としては使えません。測定装置が、測定対象に影響を与えてしまっている状態です。
遅い子ほど、強く効いてしまう
最後に、これがいちばん決定的でした。残り時間の表示は、作業が速い子には何も起きず、遅い子・集中が続きにくい子にだけ圧としてかかります。
そしてこのアプリを本当に必要としているのは、たぶん後者の家庭です。いちばん届けたい相手にだけ悪く作用する機能を、わざわざ作る理由はありませんでした。
判断の要点 「実装上は無関係だから問題ない」という説明は、開発者にしか通じません。ソフトウェアの機能は、内部の配線ではなく、画面に出たものが利用者にどう見えるかで決まります。とくに相手が子どもの場合、この差は大きくなります。
そもそも、何のために時間を測っているのか
判断のよりどころになったのは、この機能を作った目的でした。
RingiQuest では、お手伝いの対価を「想定時間 × 1分あたりの単価」で計算します。だから想定時間が実態とずれていると、対価も自動的にずれます。ところがその実際の所要時間は、これまで完了後に思い出して入力する任意の欄でしか集められていませんでした。
この数字は、家庭の基本レートの見直し提案にも使われます。つまりアプリの中でいちばん影響範囲の広い数字が、いちばん精度の低い方法で集まっていた。計測機能は、その供給側を直すために作ったものです。
目的が「正確な記録」であるなら、答えは自動的に出ます。急かした瞬間に、記録の精度は落ちる。カウントダウンは、この機能が存在する理由と正面から衝突していました。
代わりに置いたもの——減るものではなく、増えるもの
とはいえ、全画面に経過時間の数字だけが浮かんでいるのは、少し寂しい。子どもが「あとどれくらい?」と思ったときに、何かを返したい。
そこで置いたのが、減るものではなく、増えるものです。
- 「きょう おわらせた ○こ」——その日に完了したクエストの件数
- 「○にち れんぞく」——連続で取り組んでいる日数
どちらも、いま取り組んでいる作業の速さとは無関係です。急いでも増えないし、ゆっくりやっても減りません。それでいて、画面を見たときに「自分はここまでやってきた」という手応えは返ってくる。
0のときは、何も出さない
ここには細かいルールを入れました。件数が0のときは、その行を出しません。両方0なら、枠ごと出しません。
理由は単純で、この枠の目的が「がんばりを認めること」だからです。その日まだ何も終わっていない子に「きょう おわらせた 0こ」と表示するのは、目的の真逆になります。
しかも、1件目に取りかかった瞬間こそが、この画面を最初に開くときです。いちばん最初に見る画面で0を突きつける設計になっていた、というのは、実装してから気づきました。同じ理由で、データの読み込み中や取得に失敗したときも表示しません(0と区別がつかないので)。
横に2つ並べるのをやめた話
もうひとつ、実装してみて分かったこと。この2行を横2列に並べる案を最初に試したのですが、やめました。
RingiQuest には表示することばを3段階から選ぶ機能があり、いちばんやさしいレベルでは「きょう おわらせた 12こ」のように、ひらがなが多く文が長くなります。これが幅360ピクセルの画面の半分に収まらず、数字と「こ」の間で改行されるのです。「12」と「こ」が別の行に分かれる表示は、さすがに読めません。全幅1列に直しました。
測った時間を、対価に直結させなかった理由
カウントダウンと同じ種類の判断を、もうひとつしています。測定した実績時間を、支払うポイントの計算に使っていません。
対価はこれまでどおり「想定時間 × 単価 × 難易度」で決まります。実測は記録として残るだけです。
実測で払うと、放置が最適戦略になる
理由は明快で、「実際にかかった時間で払う」しくみにすると、タイマーを回したまま何もしないのがいちばん得になるからです。
子どもを疑っているのではありません。抜け道のあるしくみは、いつか必ず誰かが気づきます。そして気づいた瞬間、しくみ全体への信頼が消えます。「まじめにやっている人が損をする」構造は、家庭のルールとしていちばん壊れやすいものです。
異常に長い記録は、そもそも保存しない
関連して、極端に長いセッションは実績時間として記録しない設計にしています。夜に「はじめる」を押してそのまま寝てしまえば、経過時間は14時間になります。この数字を記録に混ぜると、この機能が直そうとしている分析を、直す前より汚してしまいます。
基準は「想定時間の3倍まで(ただし最低でも1時間、最大で8時間)」としました。下限を1時間に置いたのは、想定5分のクエストに30分かかるのはごく普通のことだからです。3倍で切ると、そういう正常な記録まで捨ててしまいます。
上限を超えた場合は、実測としても自己申告としても記録しません。何も残らなければ、単に集計から外れるだけで済みます。まちがった数字を残すより、何も残さないほうがましだという判断です。加えて、開始から6時間を過ぎたセッションは夜間の処理で自動的に中断します。「進行中」の表示が何日も出たままになるのを防ぐための、念のためのしくみです。
「作らない」を、あとから守るために
ここからは、やや技術寄りの話です。
「この機能は作らない」という判断のいちばんの弱点は、後から誰かが(半年後の自分を含めて)良かれと思って足してしまうことです。しかも足したところで、画面は普通に動きます。バグではないので、テストも通ります。
コメントに書くだけでは守れない
まずコードのコメントに警告を書きました。全画面のコンポーネントの冒頭と、文言を定義しているファイルの該当箇所です。設計ドキュメントにも書きました。
ただ、コメントは読まれなければ効きません。そして機能を足そうとしている人は、たいてい別のファイルから作業を始めます。
だから「無いこと」をテストした
そこで、ブラウザを自動操作するテストの中に、全画面の表示に「のこり」や想定時間が現れないことを検査する項目を入れました。あわせて「積み上げの数字が0のときは枠ごと出ないこと」「『とじる』を押しても計測が中断されないこと」なども確認しています。
こうしておくと、誰かがカウントダウンを実装した瞬間にテストが赤くなります。設計判断が、レビュー待ちの「お願い」ではなく、自動で検出される「約束」になる。
これはこのプロジェクトで何度かやっている手法です。たとえば AI 機能で使うモデルについても、コメントで「高価なモデルを使わないこと」と書く代わりに、単価表と上限をコードに書いてテストで固定しています。判断の理由はコメントに、判断そのものはテストに。この分担が、いちばん壊れにくいと感じています。
一般化すると 「やらないと決めたこと」は、実装した機能と同じくらい重要な仕様です。仕様である以上、テストで守れます。「無いこと」を検査するテストは書きにくいと思われがちですが、書けるものは書いておくと、判断の寿命がはっきり延びます。
個人開発で機能を削る判断について
個人開発では、作る判断は簡単です。誰の承認も要りません。難しいのは削る判断で、これは自分で自分の作業予定を否定することになるからです。
今回それができたのは、「この機能は何のために存在するのか」が一行で書けていたからだと思います。「所要時間を正確に記録するため」。この一行と照らし合わせれば、カウントダウンが目的に貢献しないどころか反対方向に働くことは、すぐに分かります。
逆に言えば、目的が一行で書けていない機能は、削る判断ができません。何を足しても「まあ、あってもいいか」になってしまう。そして、あってもいいものを足し続けたソフトウェアは、たいてい誰にとっても使いにくくなります。
代わりに置いたものについても、同じ物差しで決めました。「きょう おわらせた ○こ」は、記録の精度に影響しません。だから置いてよい。「のこり ○分」は影響する。だから置かない。判断の基準さえ決まっていれば、個々の機能で悩む必要はほとんどなくなります。
まとめ——引き算が仕様になることもある
作らなかった機能について記事を書くのは妙な感じもしますが、このアプリで下した設計判断の中では、かなり重要な部類に入ると思っています。
子ども向けのソフトウェアでは、「実装上は無関係だから大丈夫」という理屈が通りません。画面に出たものが、そのまま体験になります。数字が減っていく表示は、それだけで急かしになる。急かせば、測ろうとしていたものが測れなくなる。
時間を測る機能なのに時間を急かさない、というのは一見ちぐはぐですが、測ることと急かすことは、まったく別のことです。混ぜないようにしたい、と考えています。
急かさないタスク管理を、試してみませんか RingiQuest は、親子のためのタスク&ごほうび管理アプリです。おうちのお手伝いを「クエスト」に、ほしいものは「稟議」で申請。完全無料で、アプリ本体には広告も第三者トラッカーも入れていません。
RingiQuest を無料ではじめる