Умри пытаясь, или Как я делал первую украинскую версию Wordle, а сделал — третью

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

В этой заметке я хочу рассказать о создании веб-приложения, почти не имея такого опыта, о своего рода персональном хакатоне. Она вряд ли будет интересна техническими решениями или преодоленными трудностями, скорее историей немного самонадеянных шагов и, может быть, кое-какими уроками. Так вышло, что это приложение — украинская адаптация нашумевшей игры Wordle.

О ней я впервые узнал в начале января из рассылки The Hustle, которую, к слову, горячо советую всем, кто хотел бы быть в курсе технологических трендов хотя бы за неделю до того, как прочесть о них в %your_favorite_media%. Игра понравилась мне и я стал рубиться в нее каждый день — в точности как задумывал автор и как делали еще 300 тыс ежедневных игроков на то время.

Спустя неделю, когда это число выросло до 2 млн, новости о ней начали появляться в ленте. Тогда меня осенило: мысль о ее локализации, казалось, лежала на поверхности, ожидая, кто возьмет ее первым. Результаты поиска по запросу «Wordle українською» обнадеживали, а с выходом русскоязычного аналога вопрос внезапно стал делом чести для украинского айти. Действовать решено было незамедлительно!

О чем вообще речь

Wordle — это игра, в которой нужно угадать слово из 5 букв не более чем с 6 попыток. После каждой попытки игроку сообщается, какие буквы он угадал точно, какие — не на своем месте, а какие — вообще не угадал. Изюминка — все игроки угадывают одно и то же слово, причем по одному в день.

Игру буквально на коленке написал Josh Wardle (отсюда название) для своей подруги еще весной, а к концу года она стала вирусной. Автор при этом не планировал ровным счетом никакой монетизации и, более того, решительно отклонял заманчивые предложения с упоминанием денежных сумм, которые даже не помещались в игровое поле. Чудак, скажете вы? Возможно, но в новостях пока что читаем мы о нем, а не наоборот. Кстати о новостях.

Хотя поиск ничего не выдавал, было понятно, что это гонка на время. Вряд ли я был единственным, у кого засвербело. Каждый день я начинал с мониторинга новостей. Так начался понедельник, когда я впервые открыл свежую папку в VS Code, поглядывая с робкой надеждой на пятницу.

Вызовы

Для уверенного фулл-стека браузерная игра в слова, к тому же с уже известной реализацией — задачка на пару вечеров. Но я не уверенный фулл-стек, а UX-дизайнер с некоторым опытом веб-разработки, преимущественно фронт-энд, да и то ограниченной главным образом версткой и JS/React на уровне 0.375 джуниора. Интуиция опыт тем не менее подсказывал, что я скорее всего справлюсь, но это не точно.

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

  • React-приложение на клиенте.
  • БД на сервере со словарем, из которого каждый день отбирается одно слово.
  • Бэк-энд с API, по которому он отвечает на попытки клиента угадать его.

При этом хорошо бы иметь два словаря:

  • Ограниченный часто встречающимися словами, чтобы не загадывались малоизвестные варианты вроде «ґедзь».
  • Содержащий вообще все 5-буквенные слова для проверки пользовательского ввода.

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

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

Решения

Берясь за адаптацию готового приложения, казалось бы, логично рассмотреть вариант заимствования кода. Делать этого не хотелось: во-первых, не уверен, насколько это этично, во-вторых, было интересно сделать все самому, в-третьих, беглый осмотр показал, что игра построена на решениях, которыми я не владел (Web Components), а разучивать их просто не было времени. Большую часть JS-кода оригинала я, к тому же, был даже не в состоянии понять, хотя, вероятно, так и задумывалось.

Решено было верстать с нуля, после чего разобрать код на React-компоненты и добавить логику. Конечно же, никаких тестов, коммиты в мастер и деплой руками — все как в лучших домах Мумбая!

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

  • По сути, mobile-first-and-only верстка.
  • Необъяснимое разнообразие UI-решений для родственных задач (попап, оверлей).
  • Просившийся на выход ради экономии времени Hard Mode.

Хостить фронт-энд планировалось на GitHub Pages. Сервер, как ожидалось, будет развернут где-то еще. Впрочем, скоро уверенность в таком подходе начала шататься. Не хотелось хоститься в разных местах, да и серверная логика не выглядела такой, ради которой стоило городить огород из зоопарка технологий. Стал поглядывать сперва в сторону ExpressJS, serverless БД, а затем и вовсе на NextJS, который из коробки поддерживает API-запросы, к тому же суть знакомый мне React.

Ради интереса полез в devtools поизучать реализацию оригинала, где во вкладке Network не обнаружил ровным счетом никакой активности, а во вкладке Sources — вот такой сюрприз:

Похоже, никакого бэк-энда и нет! Оба словаря — поменьше и побольше — сразу же грузятся на клиент. Но как в таком случае все клиенты синхронно выбирают одно и то же слово для угадывания? Поиск сегодняшнего слова в массиве дал обескураживающий ответ: просто по порядку! Заходим в Local Storage — а там и вовсе объект с полем solution и ответом напротив него. Короче, нам подходит!

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

Дело было за малым, в смысле за большим: нужен был массив слов. А точнее, 5-буквенных слов. А точнее, 5-буквенных существительных. А точнее, 5-буквенных существительных в именительном падеже единственного числа, не являющихся именами собственными. А точнее, два массива.

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

А тем временем грянул ⚡️

Что было дальше

«Програміст запустив додаток „Кобза“. Це — Wordle українською», — сообщали в новостях. Иными словами, поезд начал стремительно уходить. Утешало то, что это было приложение на iOS, целый выводок англоязычных клонов которых AppStore перед этим успел забанить за нарушение авторских прав. Не только лишь все, но мало кто из них удосужился хотя бы упомянуть автора идеи.

Между тем написал письмо Джошу с вопросом о том, как он вообще смотрит на мою инициативу адаптации его игры. Отвечать он не стал, впрочем нетрудно представить себе его инбокс в эти дни. Хочется надеяться, что он не против.

Любопытно, что для многих эпигонов идея одного слова в день оказалась невыносимой, и вместо нее (или иногда вместе) они предлагали режим непрерывной игры. Между тем именно это ограничение, на мой взгляд, стало причиной взрывного успеха оригинала, заставляя игроков возвращаться снова и снова.

Словом, внимание медиа нам уже не светило. Оставалось хотя бы довести начатое до конца. Как раз подвезли данные, а вместе с ними — весть о еще одном конкуренте, который, кажется, пошел по пути повторного использования кода с локализацией одних только строк. Их качеством он при этом, правда, не блистал, что, кстати, можно было сказать и о приложении выше, хотя, насколько мне известно, оба с тех пор подняли планку.

Что до нас, то никаких козырей, кроме разве что (неидеальных, впрочем) словарей, которые мы тем временем решили минимально защитить обфусцированными функциями, в нашем распоряжении к этому моменту уже не было. Финальный деплой на шестой день как у бога производился уже чисто из принципа, хотя я соврал бы, если бы сказал, что не считаю нашу адаптацию Wordle українською наиболее удачной:

Выводы

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

  • Идея хранить отгадки в открытом виде на клиенте звучит абсурдно, но именно это упростило архитектуру до элементарной, сделав игру доступной офлайн. Что же до читерства, то, как подметил один ноунейм на реддите, cheating at wordle is dumb.
  • Уже упомянутое выше ограничение в одно слово за день. Дико? Да. Круто? Да.

Попытка воспроизвести успех преподносит уже свой горький урок. Согласно нему первый получает все, второй и последующие — ничего. В то же время это не было единственной или даже главной целью. Мною двигал, в первую очередь, интерес. Внимание аудитории — мотивирующий довесок, за ширмой которого можно обнаружить ценный опыт.

Проект не открыл мне новых технологий, разве что дал возможность познакомиться с отдельными фичами вроде Local Storage. Вместо этого я понял, как многого можно добиться уже имеющимися в моем распоряжении средствами, более того, эти средства иногда гораздо проще чем ты готов вообразить.

Самым сложным для меня всегда был старт: настроить компиляцию SCSS, ES2015, live server, заставить проект завестись в первый раз. Иногда на это уходит целый вечер археологических изысканий на StackOverflow в попытке победить ошибку модуля в командной строке. Но должен сказать, что с каждым годом dev experience становится все дружелюбнее к новичкам. VS Code с плагинами решают львиную долю задач быстрого запуска. Что и говорить, если это под силу уже даже дизайнеру. Вот бы еще только Babel Compile on Save кто-нибудь реанимировал.

Сподобалась стаття? Натискай «Подобається» внизу. Це допоможе автору виграти подарунок у програмі #ПишуНаDOU

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

"Бімба"©™

лингвистическим анализом укрнета занимался

Про оце було б цікаво почитати і подивитись результати

Круто! Якось тоді треба буде зібрати всі результати гарно з діаграмками, напишу якусь статтю про це, якщо цікаво.

Не треба діяграмки

Напишіть в графоманському стилі, і якщо сподобається сам процес, то тоді робіть як статтю для дисертації

сьогоднішнє слово було як на словко 2 дні тому. співпадіння чи алгоритм відбору слів той же?

Думаю, совпадение. У нас словарь для загадывания небольшой, ~600-700 слов.

Сам був трохи в шоці, бо не вгадав це слово ні на Словку, ні на Wordle-UA. Насправді чистий рандом, що так співпало. Але доволі цікаво справді, кісєльов тут мав би всі підстави видати свою коронну фразу :)

Ще кобза є ))

А тем временем — медальный зачет:

  1. Франция: 9 (!!!)
  2. Германия, Израиль: 7
  3. Швеция: 6
  4. Португалия (хотя, возможно, здесь и Бразилия): 4
  5. Голландия, Индонезия, Италия, Норвегия, Польша, Украина, Япония: 3
Уверен, можем лучше!

Можна збільшувати лічильник.
Я ее втримався і зробив свою версію української wordle — xvadim.github.io/wordle_ua Грати можна on-line. Або встановити PWA чи Android-додаток (скоро, він ще розглядається Google) і грати off-line. Також є можливість подивитись значення загадоного слова. Я основну увагу приділяв саме Android-додатку. Мені так зручніше грати. Web- та PWA-варіанти зробив Flutter.

Норм, только:

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

Там, кстати, прямо сейчас проводится хакатон на флаттере с неплохими призами.

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

Українською цікавіше бо немає сайтів-рішень для скреблу або словників з пошуком по вайлдкардах.

Деякі англійські слова з wordle я не знав, тому довелось шукати із словником.

Читерские сайты не имеют значения, если играть самому на интерес.

Складно грати на інтерес коли ти слова не знаєш. Вгадувати букви як у полі чудес чи що.

Доброго дня! Я автор ще одного конкурента, як ви висловилися. Так якість слів у всіх трьох реалізаціях бажає кращого. Їх треба чистити. Попадаються або дуже рідкісні, або архаїзми чи архаїчні комуністичні абревіатури, як у вашій версії, зокрема ВЛКСМ

Я бы не считал архаизмы и редкие слова в проверочном словаре проблемой. Хуже когда:

  • То или другое оказывается в словаре для загадывания
  • В проверочном словаре не оказывается часто встречающихся слов

то виходить, що «ґедзь» погано, а влксм — добре?

Есть два набора слов: для загадывания и для проверки пользовательского ввода. Для первого оба эти слова — плохая идея. (И ни одного из них в нем нет.) Кстати, где вы прочитали, что «влксм — добре»?

Вітаю з першим реалізованим веб-застосунком! Чи плануєш тепер наважитись зробити дрейф з UX у веб-розробку після стількох років досвіду саме дизайнером?

Да нет не знаю)

Підписатись на коментарі