Дневник разработки · День 8

Сел тестировать оплату — вышел из поезда с двенадцатью языками

Вчера я закончил на том, что сажусь за экран покупки. И что придумать цену мне страшнее, чем написать.

Сегодня история вообще не про цену.

Она про то, как я надумал делать переводы.

Но началось всё, как и обещал, с оплаты.

💳 Виртуальные деньги

В первый день я писал, что в поезде не поднимешь окружение и не погоняешь приложение.

Сегодня я сижу в вагоне и покупаю собственное приложение. Снова и снова.

Деньги, конечно, ненастоящие. Xcode умеет притворяться магазином: описываешь товар в одном файле, и покупка проходит целиком — окно, подтверждение, ответ магазина. Без сети и без единого настоящего доллара.

С платформой Apple напрямую я дела почти не имел. Поэтому было по-настоящему интересно, как это будет выглядеть.

Выглядит классно. Всё понятно и грамотно, и с Xcode я заодно познакомился чуть ближе.

Потестировал. Поделал виртуальных оплат. Поснимал их обратно. Погонял туда-сюда — посмотрел, как всё работает в обе стороны.

Заодно добавил счётчик, который намекает, что лимит подходит к концу. Появляется он, только когда осталось восемь, — не раньше.

Ничего сверхъестественного. Развлечение минут на тридцать.

А вчерашний страх никуда не делся.

Сама цена висит на лендинге с первого дня: $9.99, один раз. Страшно не число. Страшно — сработает ли оно.

Не слишком ли дорого? Не слишком ли дёшево? Где баланс между тем, сколько отдать бесплатно, и тем, за что людям будет приемлемо заплатить?

Ответа у меня нет. Есть только другая сторона.

Я тут хороший парень.
Не лезу в карман подпиской.
Не прошу оплату сразу.
Даю разумный лимит, чтобы попробовать.
Не жадничаю с разными платформами.

В общем, топ за свои деньги.

И про лимит. На том же лендинге с первого дня висит ещё одно число. Я тогда просил его запомнить и обещал к нему вернуться.

Вот оно.

Скрин этого развлечения, которым я сегодня поделился с другом. Сюда упирается бесплатный тариф: двадцать четыре сниппета, дальше $9.99 — один раз.
Скрин этого развлечения, которым я сегодня поделился с другом. Сюда упирается бесплатный тариф: двадцать четыре сниппета, дальше $9.99 — один раз.

Двадцать четыре сниппета бесплатно и навсегда. С сегодняшнего дня это число живёт не только на странице, но и в коде.

И пара деталей, которые мне нравятся больше, чем следовало бы.

Предел стоит не на кнопке, а там, где сниппет создаётся. Иначе любой другой путь его бы обходил.

Сниппеты при этом не читаются, а только пересчитываются. Содержимое сейфа остаётся зашифрованным, наружу выходит одно число.

Счётчик, который не читает то, что считает.

И отказ ничего не стирает. Раньше человек набрал бы строку, нажал — и вместо сниппета получил окно про покупку, а строку потерял. Теперь создание честно отвечает, сохранило оно или нет, и то, что не поместилось, остаётся в поле.

👹 iddqd

С оплатой я закончил где-то между Ниагарой и Гамильтоном.

А по Гамильтону ехал уже с другим в голове. Дальше жопу потянуло на развлечения.

Ну нельзя же сделать приложение без пасхалок.

А что может быть лучше, чем вспомнить что-нибудь древнее. Настолько древнее, как Doom.

Насколько я догадываюсь, такие коды часто ставят не ради веселья. Через них проверяют пути распространения: кто откуда пришёл, какой код ввёл, что сработало.

У меня такой телеметрии нет.

С самого начала я заложил в приложение правило: у нас нет доступа к данным на стороне пользователя. Ни бэкенда, ни аналитики.

Я просто сильно не люблю такие приколы.

Когда ты не знаешь, до какой грани твои данные ещё твои, а откуда начинается жёсткий абьюз.

Когда кто-то в любой момент может поменять политику сбора информации, просто прислав апдейт на почту.

Мне такое говно не нравится.

Поэтому здесь пасхалка — просто развлекуха. Ну и вам, читателям, будет занятно.

И в этом свете я заодно переосмыслил лимиты.

Двадцать четыре остаются. Но если ввести чит-код из Doom — станет на десять больше.

Ну или меньше. Читы там были разные.

Как зайдёт — расскажете)

Сделано, впрочем, всерьёз.

Десять не прибавляются, а выставляются. Вводи код хоть сто раз — сверху будет ровно десять, не больше. И бонус записан в настройках, так что переживает перезапуск.

А если ввести код после покупки, давать уже нечего. Тогда приложение просто отвечает: «God mode у тебя куплен. Молнии — за счёт заведения».

Потому что за курсором ещё и тянутся молнии.

Пользы от них ноль. Но и они сделаны аккуратно. Рождаются от слежения за мышью, а не от прозрачного слоя поверх всего — иначе такой слой перехватывал бы нажатия у каждого блока под ним. А рисование засыпает само, когда не осталось ни одной молнии, так что неподвижный курсор не стоит ничего.

Я потратил время на то, чтобы бесполезная вещь была сделана правильно.

А вот как вся эта пасхалка стыкуется с остальным приложением — не вникал. Идея была самоценной.

Тоже минут на тридцать.

🎮 Полчаса Ведьмака

А в поезде мне ехать два часа.

Так что сегодня я себе таки разрешил потратить полчаса на Ведьмака.

Вчера вышел ремастер. Тот самый, который в понедельник лежал на свиче и ждал волшебной даты.

И знаете…

Мой родной язык — не английский.

И как же прикольно поиграть в игрулину на своём языке.

Это как удобные тапочки. Именно твои, и на твоём языке.

Подумал я об этом уже на подъезде к Торонто.

И решил прикинуть: а сколько времени это займёт у меня?

🌍 Двенадцать языков до офиса

Как выяснилось — да не то чтобы сильно долго.

Английский был с самого начала. Добавилось двенадцать: русский, украинский, немецкий, французский, испанский, португальский, итальянский, японский, китайский, корейский, бенгальский и хинди.

Язык берётся системный. Включать ничего не надо.

Переводит, конечно, не я — переводит ИИ. Проблема была в другом: проверить всё приложение на тексты, которые остались непереведёнными.

В 2026 году это не так трудно, как кажется. Просто берёшь и пробуешь.

Это правда больше тест на внимательность, чем на знание.

Например, список строк, которые надо перевести, нельзя собрать поиском по файлам. Строки внутри условий и строки с подставленными числами поиск не находит — их пришлось брать из того, что видит сам компилятор.

А часть надписей молча осталась бы английской. Есть два способа вывести текст, выглядят они одинаково, и один из них не переводит. Заголовки разделов, строки настроек, первое знакомство с приложением, подписи у цветовых ползунков — всё вокруг перевелось бы, а это осталось.

И тут помогают сами языки.

Хинди, бенгальский, японский — идеальная среда, чтобы увидеть, где какое слово или уведомление не переведено. Английское слово посреди деванагари не спрячется.

Три языка из двенадцати я знаю сам, их проверю сам. Ещё поспрашивал коллег: нашлись знатоки хинди, бенгальского, корейского и японского. Так что есть с кем это дело проверить.

Имя доски решается в момент, когда её создали. Доска, названная на русском Mac'е, остаётся с русским именем, даже если систему потом переключат.

И главное.

Шутки в приложении не переведены. Они написаны заново, каждая под свой язык.

Помните «ну или меньше»? У каждого языка на этот случай своя пословица про наказанную жадность. Не одна пословица в двенадцати вариантах, а двенадцать разных.

Одна и та же строка на двенадцати языках. По-английски там просто «Too greedy».
Одна и та же строка на двенадцати языках. По-английски там просто «Too greedy».

А «god mode» в пяти языках уступил место местному слову. В хинди и бенгальском это дар. В японском, китайском и корейском — режим неуязвимости. Английское геймерское словечко там лежит инородным телом, а шутка, которую надо объяснять, — уже не шутка.

Ну и настройки пришлось расширить на шестьдесят пунктов. Ползунок занимал сто сорок, на подпись оставалось около ста двадцати, и языки подлиннее в них не влезали.

Двенадцать языков — это не двенадцать файлов. Это двенадцать разных представлений о том, сколько места занимает слово.

Когда я выходил из поезда, я был тем самым странным парнем с открытым ноутбуком в руках.

Но ещё до того, как я зашёл в офис, у меня было двенадцать языков.

Да, их ещё надо прочитать и проверить. Никто не идеален.

Но это то, что может хорошо помочь с продвижением. И вот почему.

Англоязычный рынок самый прибыльный. Но вместе с этим и самый конкурентный.

Если делать из моего продукта то, что будет продаваться, то лучше делать охват побольше.

🔌 Engineer honesty moment

Полчаса развлечений у меня сегодня ушло на деньги и полчаса на пасхалку. А вот три вещи из того же дня, которые развлечением не были.

Первая — гонка. После того как покупка завершена, у системы можно спросить, что человеку теперь принадлежит. Я спрашивал сразу.

Слишком сразу. Покупка уже прошла, а ответ ещё говорит «ничего не куплено».

Теперь право даётся из самой подписанной покупки, а переспрашивать систему имеет смысл в одном случае — когда покупку отозвали.

Вторая — возврат. И вот тут смешно. До сегодняшнего дня отозвать покупку было нельзя вообще.

Флаг «куплено» умел говорить только «да» и «нет». А «ещё не спрашивали» и «спросили, покупки нет» оба выглядели как «нет». Поэтому, если человек вернул деньги, приложение этого просто не замечало и оставалось разблокированным навсегда.

Теперь у флага три состояния. И он — кэш, а не решение. Решает всегда магазин.

Разница между кэшем и решением — примерно всё, что нужно знать про деньги в приложении.

Третья — смена уровня приватности. У доски их три: обычная, защищённая отпечатком, сейф с паролем.

И было странно, что их можно вот так просто переключать.

Сменить уровень мог кто угодно, у кого перед носом открытое приложение. Доска уже разблокирована — значит свой, значит можно.

Нет.

Разблокировано — это не доказательство. Это значит, что кто-то доказал право один раз, а потом отошёл за кофе.

Незнакомый человек у незапертого Mac'а мог перевести вашу доску в сейф со своим паролем. И запереть вас снаружи вашей же функцией.

Теперь смена уровня требует доказать тот уровень, на котором доска стоит сейчас, даже если она открыта. А новый уровень включается сразу: пароль проверяется в момент, когда его придумали, а не в тот момент, когда его забыли.

Закрыть-то закрыл. Но весь этот блок ощущается очень большой штукой, которую ещё тестировать и тестировать.

💬 Вопрос

О цене я думаю с тех пор, когда не было ещё ни строчки кода. Языки сделал по дороге в офис.

Сколько вы готовы один раз заплатить за маленькую штуку, которой пользуетесь каждый день? И сколько бесплатного вам нужно, чтобы это понять?

Мой ответ пока такой: двадцать четыре сниппета, чтобы по-настоящему попробовать, и дальше $9.99 — один раз и навсегда. Сработает ли — не знаю.

Расскажите, как у вас 👇

Двенадцать языков у меня есть. Прочитанных — пока ни одного.

Завтра хочу пройтись по всему приложению глазами того, кто будет проверять его перед магазином. И подозреваю, мой чит-код ему не понравится 😉