#mopsicus: заметки с тегом js https://mopsicus.ru/tags/js/ об играх, разработке на Unity и личном опыте Игорь Лопатин ru E2 (v3572; Aegea) Игорь Лопатин об играх, разработке на Unity и личном опыте Лото и ChatGPT 😅 269 https://mopsicus.ru/all/loto-cards-generator-chatgpt/ Tue, 03 Dec 2024 12:00:07 +0300 Игорь Лопатин https://mopsicus.ru/all/loto-cards-generator-chatgpt/ <div class="e2-text-picture"> <h3 style="display: none;" itemprop="name">Russian Loto cards generator</h3><h4 style="display: none;" itemprop="description">Russian Loto cards generator</h4><img itemprop="contentUrl" src="https://mopsicus.ru/pictures/loto-generator.png" width="1664" height="1974" alt="Russian Loto cards generator" /> </div> <p>Как-то мы захотели поиграть в Русского Лото, классическое, оффлайновое, там где мешок, бочонки, карточки. Но людей много, а карточек мало, к тому же они от игры к игре повторяются. Хотелось полного рандома. Думал зайду в Google, скачаю генератор и распечатаю сколько мне нужно новых карточек. Но оказалось, что такой штуки просто нет 🤷‍♂️ Ну или я плохо искал.</p> <p>В общем, самому писать такое было неинтересно, да и некогда, поэтому решил проверить победили ли нас машины или нет, надо уже менять профессию или нет — попробовал написать всё с помощью ChatGPT. В итоге получилось всё как я хотел, но надо сказать, что это было не как в фильме Железный человек, когда Джарвис всё понимал с полуслова. В какой-то момент хотелось уже руками поправить код и забыть, но интересно было именно таким способом сделать от начала до конца.</p> <p>Получился <a href="https://gist.github.com/mopsicus/120f2e808cb22801a5c0ba2758775af1">генератор карточек для игры в Русское Лото</a>, в виде одной HTML странички, весь HTML и код на JavaScript сгенерил ChatGPT, я ни строчки не написал :) Можно указать количество страниц для генерации, и на каждой будет 4 карточки с рандомными числами в соответсвии с правилами игры. Файл сохраняется в PDF.</p> Unity и WebGL 257 https://mopsicus.ru/all/unity-webgl-tips/ Sat, 23 Apr 2022 17:50:39 +0300 Игорь Лопатин https://mopsicus.ru/all/unity-webgl-tips/ <div class="e2-text-picture"> <h3 style="display: none;" itemprop="name">Unity WebGL tips</h3><h4 style="display: none;" itemprop="description">Unity WebGL tips</h4><img itemprop="contentUrl" src="https://mopsicus.ru/pictures/unity-webgl-tips.png" width="1204" height="835" alt="Unity WebGL tips" /> </div> <p>Не от хорошей жизни пришлось делать WebGL версии наших мобильных игр :) Т. е. изначально, игры не продумывалась для браузера, но тем не менее, после небольших доработок и рефакторинга — всё необходимое заработало. Эта статья как раз для тех, кто задумался над выпуском версии для веб: набор из нескольких наблюдений, советов, собственных мыслей и велосипедов.</p> <p><b>Вебсокеты</b>. Так как у нас все игры — онлайн, то первое что сделал — поддержка сети. В мобильных играх у нас используются TCP сокеты, для браузера же надо использовать вебсокеты (WebSocket). И сразу надо сказать: C#’ские вебсокеты работать не будут. Надо брать готовый или писать свой JS плагин. И в качестве примера, в телеграм канале я уже постил <a href="https://github.com/jirihybek/unity-websocket-webgl">этот реп</a>. Он старый, работает и для примера пойдёт. Там кстати сделана поддержка вебсокетов в редакторе (уже через C#’ские). Т. е. можно дебажить и билдить, работать всё будет. В ассетсторе тоже есть разные реализации вебсокетов для WebGL, можно поискать, есть и Socket.IO, Mirror.</p> <p class="note">Да, для WebGL тоже можно и нужно <a href="https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html">писать плагины</a>, как и для Android и iOS.</p> <p>В общем, в браузере много что работать не будет и особенно всё что связано с мобильной платформой: галерея, авторизация, пуши, буфер обмена, платежи — это всё надо делать или через JS плагины, менять реализацию или вообще отказываться.</p> <p><b>Платежи</b>. Google Play и AppStore не работают в WebGL. В том смысле что нельзя получить информацию о продукте (описание, цена и т. д.) и сделать покупку в браузере. Поэтому мы сделали просто: вместо запроса списка продуктов, делаем запрос к нашему серверу (сервер определяет что клиент WebGL) и в ответ получаем примерно такую же структуру: цена: описание, количество. Но самое главное — приходит ещё и ссылка для оплаты! Т. е. для пользователя визуально всё осталось также, но при попытке оплаты открывается новая вкладка с сформированной ссылкой на оплату нужного товара. А тут уже можно подключить любой удобный сервис приема платежей и по коллбеку успешной оплаты начислять пользователю определенное количество продукта. Вот такие антисанкции.</p> <p><b>Загрузка изображений</b>. Тут проще, в браузерах уже есть встроенный механизм загрузки файлов, его и можно использовать. Вот <a href="https://github.com/greggman/getuserimage-unity-webgl">пример как это реализовано</a>, а на SO можно <a href="https://stackoverflow.com/a/35201934">прочитать</a> как автор до этого дошёл. К слову, этот код рабочий. Немного корявенький, требует рефакторинга, но работает. Картинка приходит в Unity в base64, раскукоживаете её в массив байт и дальше уже что требуется: отправляете на сервер, используйте в игре и т. п.</p> <p><b>Уведомления</b>. Все ненавидят уведомления в браузере. И у нас их скорее всего не будет. Но раз обещал, напишу что сохранил для себя если вдруг надумаем (или вы надумаете) делать пуши: плагин можно собрать из таких <a href="https://forum.unity.com/threads/unity-webgl-firebase-cloud-messaging-jslib-plugin.837307/">запчастей</a>, честно не пробовал ещё, скорее всего буду свой писать :) Это <a href="https://firebase.google.com/docs/cloud-messaging/js/client">Firebase Cloud Messaging</a>, он бесплатный и вообще можно отсылать пуши на все платформы. Для реализации на своем сервере, например для NodeJS, можно погуглить <a href="https://www.npmjs.com/package/web-push">web-push</a>. На Хабре есть статьи, вот свежая относительно <a href="https://habr.com/ru/post/562058/">про PHP и web пуши</a>. Есть еще <a href="https://pushjs.org">pushjs.org</a>, оно вроде как работает во всех браузерах, можно устанавливать кастомный сервис-воркер. Как писать воркеры можно <a href="https://serviceworke.rs">почитать в таком cook-book’e</a>. Но опять же, всё что связано с пушами не проверял ещё.</p> <p><b>Google и Apple авторизация</b>. У нас в приложениях как раз используются такие способы авторизации. И для них есть возможность сделать веб авторизацию, чего не скажешь про Huawei ID, хотя может и китайцы скоро допилят. Так вот, тут тоже всё относительно просто: открываете мануал как сделать веб авторизацию на своем сервере и делаете: <a href="https://developers.google.com/identity/gsi/web/guides/overview">Google</a> и <a href="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/configuring_your_webpage_for_sign_in_with_apple">Apple</a>. Про Apple есть еще норм <a href="https://habr.com/ru/company/cian/blog/475062/">статья на Хабре от ЦИАН</a>. Основной момент тут — это редирект после успешной авторизации, туда можно подставить свои параметры, а внутри плагина перехватить их и использовать для авторизации уже в WebGL приложении. Вот нашел <a href="https://stackoverflow.com/a/66514111">грубый пример</a> как это может работать. Автор как и предупреждает не совсем верно использует запрос авторизации. Лучше открывать свою страницу с кнопкой(-ми) авторизации и уже после успешного завершения перехватывать редирект со своего сайта.</p> <p><b>Где размещаться?</b> В комментариях в телеге спросили на каких сервисах публикуем WebGL игры — точно будем пока на своих сайтах, для нас это больше инструмент для платежей. Но в перспективе, рассматриваем ВК и Одноклассники. Может и во вражеском ФБ, кто знает. На реддите нашёл вот небольшой <a href="https://www.reddit.com/r/webgl/comments/ek8xyq/which_are_the_best_webgl_publishing_website_for/">список</a> где можно разместиться, старый, но наверняка что-то живое есть, <a href="https://itch.io">https://itch.io</a> точно.</p> <p>И бонус, как сделать рабочий <a href="https://stackoverflow.com/a/30810322">вариант копирования в буфер обмена</a> во всех (вроде как) браузерах.</p> <p>Ну и ещё бонус, точнее анонс: мы делаем онлайн мобильную 3D игру, до этого как-то больше по 2D всё было, так что будут интересности по 3D. Подписывайтесь на <a href="https://t.me/mopsicus_ru">Telegram канал</a>.</p> Сервер на Node.js и клиент на Unity 164 https://mopsicus.ru/all/node-js-game-server-unity-client/ Wed, 08 May 2019 13:01:41 +0300 Игорь Лопатин https://mopsicus.ru/all/node-js-game-server-unity-client/ <div class="e2-text-picture"> <h3 style="display: none;" itemprop="name"></h3><h4 style="display: none;" itemprop="description"></h4><img itemprop="contentUrl" src="https://mopsicus.ru/pictures/nodejs-server-unity-client.jpg" width="515" height="222" alt="" /> </div> <p>Задумал я тут выложить на Github свою очередную поделку — простой сервер на Node.js и клиента к нему на Unity. Много раз сам гуглил различные библиотеки, пробовал, тестировал, пытался сам написать что-то (с моими познаниями в Node.js :), но потом подсмотрел как сделано у старого китайского <a href="https://github.com/NetEase/pomelo">Pomelo</a>, который уже сто лет не поддерживается.</p> <p>Если честно, когда я первый раз узнал про Pomelo и начал его изучать, то понял, что для моих текущих задач такой функциональности не требуется, поэтому решил выпилить всё что не нужно. В итоге, осталось вот что:</p> <p class="note">Опыта в Node.js у меня не очень много, поэтому я нагуглил такой фреймворк — Architect. Не знаю насколько это оправдано, но пока сделано с помощью него.</p> <ul> <li>многопользовательский сервер для <b>не</b>реалтаймовых игр</li> <li>отправка и получение команд и запросов (аналог JSON RPC)</li> <li>поддержка SSL</li> <li>основная часть на <a href="https://github.com/c9/architect">Architect</a></li> <li>простое добавление команд: один файл = одна команда</li> <li>работает с MongoDB</li> </ul> <h2>Команды (события)</h2> <pre class="e2-text-code"><code class="">public void TestCommand () { JsonObject param = new JsonObject(); param[&quot;param&quot;] = &quot;value&quot;; _connector.Command(&quot;test-cmd&quot;, param); // _connector.Command(&quot;test-cmd&quot;); // without params }</code></pre><p>Чтобы «слушать» команды с сервера надо подписаться на команду (событие):</p> <pre class="e2-text-code"><code class="">public void TestCommand () { _connector.On(&quot;test-cmd&quot;, OnTestCmd); // _connector.Off(&quot;test-cmd&quot;, OnTestCmd); // unsubscribe } void OnTestCmd (JsonObject result) { if (_connector.IsError (result)) { // handle error return; } // handle result }</code></pre><h2>Запросы (RPC)</h2> <pre class="e2-text-code"><code class="">public void TestRequest () { JsonObject param = new JsonObject(); param[&quot;param&quot;] = &quot;value&quot;; _connector.Request (&quot;test-rqt&quot;, param, (result) =&gt; { // handle answer }); // _connector.Request (&quot;test-rqt&quot;, OnTestRequest); // without params // _connector.Request (&quot;test-rqt&quot;, param, OnTestRequest); // callback in external method } void OnTestRequest (JsonObject result) { if (_connector.IsError (result)) { // handle error return; } // handle result }</code></pre><p>На RPC запросы с сервера можно подписаться также как и на обычные команды. Отличие в том, на них надо обязательно «отвечать».</p> <p>На сервере каждая команда находится в отдельном файле и экспортируется, как-то так:</p> <pre class="e2-text-code"><code class="">module.exports = function (commander, message, imports) { if (!validate(message.data, commander.protocol.log)) { commander.sendError(message, &quot;invalid_data&quot;); return; } ... commander.sendResponse(message, { result: &quot;ok&quot; }); };</code></pre><p>Протокол сообщений можно легко переделать, добавить шифрование или свой какой-то формат, можно посмотреть в репе Pomelo, у меня будет также примерно.</p> <p>Для создания простой многопользовательской онлайн игры — этого достаточно. Это будет такая демка, когда можно взять сервер и клиент, запустить и сразу увидеть как оно работает. Код будет полностью доступен, так что умеющие в Node.js и C#, смогут переписать мои «костыли» на свои :)</p> <p>После тестирования и «боевой» проверки на игре, если всё получится, думаю сделать небольшой курс, где опишу, как на основе такой базы делать несложные онлайн игры. Но замечу ещё раз — НЕ реалтайм!</p> <p>Stay tuned.</p> Riddut. Возвращение. 99 https://mopsicus.ru/all/riddut-returns/ Sat, 03 Feb 2018 21:22:31 +0300 Игорь Лопатин https://mopsicus.ru/all/riddut-returns/ <div class="e2-text-picture"> <h3 style="display: none;" itemprop="name"></h3><h4 style="display: none;" itemprop="description"></h4><img itemprop="contentUrl" src="https://mopsicus.ru/pictures/riddut-image.png" width="610" height="550" alt="" /> </div> <p>В 2015 году я сделал для себя небольшой плагин для браузера — он вырезал из ленты ВК и ФБ ненужные мне записи по стоп-словам. Всё работало очень просто: находил в ленте слово и удалял пост.</p> <p>Потом, я добавил поддержку морфологии, чтобы не добавлять кучу слов с разными окончаниями. Ещё скрипт научился удалять контекстную рекламу и фильтровать выдачу поисковых систем. И итогом стала — фильтрация любого сайта. Иногда от этого страдает вёрстка, но оно того стоит. Новостной сайт после фильтра хоть можно читать...</p> <p>После этого, я успешно про него забыл. И вот 2018 год: выборы, санкции, олимпийцы — пришло время снова очистить своё информационного пространство от, и смахнуть пыль со старого кода.</p> <p class="loud">Riddut</p> <p>Так называется расширение. Да, оно ограждает от нескончаемого потока информационного шума. Это такой персональный AdBlock для контента.<br /> Вот что умеет:</p> <ul> <li>удалять любое упоминание стоп-слова на любом сайте</li> <li>удалять посты и рекламу из соц. сетей Фейсбук, ВКонтакте, Одноклассники, Твиттер по ключевым словам</li> <li>удалять позиции в выдаче и рекламу поисковых систем Яндекс, Гугл, Бинг</li> <li>фильтровать дозагруженный контент</li> <li>работать с белыми списками сайтов</li> <li>понимать русскую и английскую морфологию (не полностью)</li> <li>синхронизироваться между браузерами</li> <li>показывать красивую статистику «сэкономленного» времени :_)</li> </ul> <div class="e2-text-picture"> <h3 style="display: none;" itemprop="name"></h3><h4 style="display: none;" itemprop="description"></h4><img itemprop="contentUrl" src="https://mopsicus.ru/pictures/riddut-how-to.jpg" width="914" height="289" alt="" /> </div> <p>Сейчас всё это дело в бета версии, так что, если расширение окажется вам полезным — напишите на <a href="mailto:mail@mopsicus.ru">mail@mopsicus.ru</a>, что добавить, убрать, исправить, улучшить. Захотите поучаствовать? Буду рад.</p> <p>Есть версии для Chrome, Safari и Opera. С Firefox пока не разобрался в чём проблема, но думаю решу.</p> <p>Подробнее на <a href="https://riddut.mopsicus.ru">https://riddut.mopsicus.ru</a></p> <p class="foot">Заметка чтобы попереживать. Да, расширение отправляет на сайт слова, чтобы с помощью библиотеки морфологии, получить в ответ все его формы и отфильтровать страницу. Ещё оно скачивает актуальные данные по вёрстке. Это всё. В любом случае, всё что отправляет и получает расширение можно посмотреть через консоль. Если вас это не устраивает, что ж, вы можете не использовать моё расширение :)</p> <p><b>Riddut</b> — это не баннерорезалка. Удаление некоторой рекламы, это приятный бонус, а не основная функция. Но вы легко можете использовать и то и другое вместе.</p>