📱 Valve під загрозою £656 млн через Steam у Великій БританіїValve може бути змушена виплатити компенсацію геймерам у Великій Британії після того, як суд дозволив продовжити колективний позов на суму £656 млн.Справа триває з 2024 року: Вікі Шотболт подала позов від імені британських користувачів Steam, які купували ігри та DLC з 2018-го. Valve звинувачують у завищених цінах та комісії до 30%.Адвокати стверджують, що Valve нав’язує видавцям жорсткі умови:🔸 не дозволяє продавати ігри дешевше на інших платформах;🔸 забороняє випускати їх раніше поза Steam;🔸 змушує купувати весь додатковий контент лише через Steam, якщо гра вже там придбана.За підрахунками, 14 мільйонів користувачів Steam у Великій Британії могли переплатити за ігри та додатковий контент. Потенційна компенсація для кожного геймера від £22 до £44, а користувачі зі Шотландії можуть отримати більше.Valve намагалася зупинити процес ще до суду, але Лондонський трибунал відхилив їхні аргументи. Дата судового розгляду поки що не призначена, і очікується, що справа триватиме кілька років.Паралельно проти Valve подано позов у США.Цей позов став ще одним у низці справ проти великих платформ. У Британії вже розглядають схожі претензії до Apple та Google через комісії в App Store і Play Store на рівні 30%.‼️ Якщо суд стане на бік позивачів, це може серйозно вдарити по бізнес-моделі Steam.✈️ Gamedev | #новини #суд #UK #Steam #Valve
🧐 Про нездоровий перфекціонізм Давайте чесно: всі, хто хоча б раз робили гру, відчували, що щось у проєкті не так, і це варто допрацювати / підкоригувати.Звичайно, це можна назвати «прагненням до досконалості», але дуже часто це перетворюється на нескінченне «ще трошки підправлю». І розробка затягується на дуже дуже довго, бо після всіх правок ви вже втомлені і нічого не хочете.⌛ Хвилинка на виплеск емоційСкажу так - жиза, база, грунт. Мені здається, я не вмію з цим боротися. Якщо я це не виправлю — "гризе" і то сильно. І якщо це, в якісь мірі, виглядає дуже сумнівно то я не хочу нічого іншого робити поки не виправлю цього (виявляється, це стосується не тільки розробки).Або якщо я й продовжу — гра виглядає, в усіх аспектах, перепрошую, гівном....Продовжимо по темі:Стикнувся нещодавно з цим, і хоча все закінчилось добре, бо тепер все як я хочу і можна з задоволенням продовжити, все ж зловив себе на думці: А як з цим боротися? Ну і чи взагалі потрібно?🔸 Чи потрібно взагалі?Так. Потрібно. Якщо це заважає вам працювати в команді або по суті не сильно щось змінилося і ви на це витратили час і емоційний ресурс — потрібно.Якщо це стосується змін після яких гра буде виглядати краще не тільки для вас (для цього є друзі, які якщо не дай бог будуть з вами не згідні значить не розуміються і у них немає відчуття стилю) і це того вартує — це прагнення до досконалості.Позволяю себе побалувати і якщо певна зміна займає не багато часу, якого вам не шкода — виправляйте, але не багато)🔸 Як з цим боротися?Пошукав в неті, спитав GPT. Ось що справді мені зайшло і що я можу додати від себе:1) Встановити “межу достатньо добре”Замість “ідеально або нічого” — “достатньо добре для релізу”.Можна написати критерії після яких можна зупинитися. Для прикладу: якщо основні елементи читабельні і не лізуть один на одного, якщо механіка працює без критичних багів, якщо загальна атмосфера передає задум.Доволі примітивно, але це лише приклад.2) Навчіться і визначте “точку безповоротності”Це можна задіяти, коли ти розумієш, що правки вже не роблять гру кращою, а просто перетягують тебе в своєрідне болото. Але це теж потрібно вміти розпізнати. 3) Попросіть допомогиЯк людина, яка 100% стикається з такою проблемою, скажу — ті хто з вами не згідні, можуть не розуміти як це має виглядати і вони просто не шарять 😅Але все ж думаю, що у всіх є хоча б один друг, у хорошому сенсі, задрот, який розуміється і може вас зупинити.4) Встановіть собі дедлайниВизначте умовну точку, до якої ви робите всі необхідні речі. А далі те саме, але вже для правок.Головне — мати сил не переносити собі ці дедлайни))5) ВідпочивайтеСкажу коротко — стикався з тим, що перезаходив після умовного "відпуску" і забував про всі правки. Гра виглядала нормально)))6) Розберіться в собіЧув, що перфекціонізм = страх. І хоча я, можливо, не повністю згідний, все ж щось у цьому є. Основна думка: “Що я боюся втратити, якщо це буде не ідеально?”. Можливо комусь допоможе 😉❓ Чи є у вас така проблема? Як ви вирішували її? Буде дуже цікаво почути.✈️ Gamedev | #запитання #перфекціонізм #продуктивність #психлікарняплаче
📱 Steam уточнив правила використання ШІПочинаючи з 2024 року, Steam вимагає від розробників вказувати використання генеративного ШІ, і тепер Valve чітко переформулювала ці правила, не скасовуючи їх.Головне уточнення: інструменти на базі ШІ для розробки більше не вважаються предметом розкриття, якщо їхній результат не споживає гравець. Вайбкодери (у тому числі автор) - можете бути спокійні 😁❓ Що саме цікавить Steam?• арт і графіка;• аудіо;• тексти та наратив;• локалізація;• маркетингові матеріали;• сторінка гри в Steam.Два типи ШІ, які потрібно вказувати:1️⃣ ШІ для створення контенту гриЯкщо ШІ використовувався для генерації контенту, який постачається разом із грою або її сторінкою — це потрібно описати текстом.2️⃣ ШІ-контент у реальному часіЯкщо гра під час геймплею генерує текст, зображення, аудіо чи інший контент — це позначається окремою галочкою.⚠️ Відповідальність на розробнику: оскільки real-time ШІ-контент не може бути повністю перевірений модерацією Steam, гравці зможуть скаржитися через Steam Overlay.✈️ Gamedev | #новини #Steam #Valve #AIinGames #ШІ
🎥 Recorder. Або як зняти свою гру в 4КМожливо вже багато з вас знайомі з цим інструментом, а можливо і ні 😅Якщо вам потрібно зняти свою гру для трейлеру/Reels/Tik Tok і т.п то цей інструмент вам допоможе.Unity Recorder — це офіційний інструмент Unity для запису відео та скріншотів прямо з редактора, без втрати якості.❓ Чому не OBS?Unity Recorder кращий за OBS і ShadowPlay, бо він рендерить кадри напряму, а не записує екран. Через це навіть при низькому FPS гри фінальне відео виходить плавним і стабільним, без лагів, дропів і втрати якості, плюс можна записувати UI, окремі камери або RenderTexture.Де знайти?Window → Package Manager → Recorder
Після завантаження → Window → General → Recorder → Recorder Window. Далі ви можете обрати камеру, яку слід відслідковувати, розширення, кількість FPS, розташування і багато чого іншого.Інструмент, ясна річ, повністю безкоштовний, тому можете його використати, щоб показати свою гру у наступному #ScreenshotSaturday 😉✈️ Gamedev | #інструменти #camera #render #GameTrailer
📱 Потоки в C#: базові поняття та ціліГеніальна фотка, правда?) 😋Всі ж пам'ятають ось цей от пост, де ми говорили про Task і Coroutines? Якщо ні - прочитайте. А якщо так, то там ви точно мали читати щось про потоки і т.п. Що таке ці "потоки" і чому вони такі важливі?Давайте розберемося трішки детальніше:Потік (thread) – це незалежна лінія виконання всередині програми. В одному процесі може працювати кілька потоків одночасно, і вони ділять одну й ту ж пам’ять.Потоки дозволяють ефективніше використовувати багатоядерний процесор: поки один потік чекає (наприклад, на зчитування файлу), інші можуть працювати. Це допомагає не блокувати інтерфейс користувача під час тривалих операцій.⚙️ Основні API: Thread, ThreadPool, Task і async/awaitНе буду забивати вам голову знову одним і тим самим, тому лише про основні моменти. Клас Thread (System.Threading.Thread): дозволяє створити новий потік.Thread th = new Thread(() => { // Код, що виконується в новому потоці Console.WriteLine("Потік виконується"); Thread.Sleep(1000);});th.Start(); // Запуск нового потоку
Thread.Sleep блокує конкретний потік, а не весь додаток.Thread – це низькорівневий ОС-потік, який створює реальний паралельний потік виконання; ти сам контролюєш його старт, завершення, пріоритет і синхронізацію.А Task – це високорівнева абстракція для асинхронної або паралельної роботи, яка не обов’язково створює новий потік, а зазвичай використовує потоки з пулу (ThreadPool); Task зручний для отримання результатів, обробки винятків та інтеграції з async/await (про них читаємо у вищезгаданому пості).❓ Про практичне використання теж можете прочитати у тому пості. Або ж у загальному:• UI-додатки (Windows Forms, WPF, Unity): не блокувати інтерфейс користувача під час тривалих операцій (завантаження файлів, мережеві запити).• Мережеві операції та I/O: Task + async/await дозволяють чекати на завершення запиту без блокування потоків.• Фонові служби та сервери: виконання різних завдань одночасно (обробка запитів, логування, таймери).ℹ️ Джерела:[Thread?] / [Thread]✈️ Gamedev | #уроки #csharp #tasks #async #thread
🚨 Steam лежить: користувачі масово не можуть підключитисяСпокійніше. Просто автор любить клікбейтні заголовки 😉Багато гравців повідомляють, що Steam не запускається або зависає на “Connecting”. Не працює вхід, Store та Community — проблема підтверджена моніторингом (SteamDB, Downdetector), зачеплені авторизація та веб-сервіси.🔎 Що робити, якщо Steam не підключаєтьсяСпочатку перевірте, чи це глобальний збій Steam (SteamDB або Downdetector). Якщо були залогінені раніше, спробуйте Offline Mode для синглплею, як в старі, добрі 10-ті роки.Якщо проблема лише у вас, спробуйте:• перезапустити Steam і ПК;• вимкнути VPN / проксі;• перевірити фаєрвол або антивірус;• очистити кеш (steam://flushconfig);• вийти зі Steam Beta або запустити з -tcp.ℹ️ Чому так?Steam обслуговує понад 30 млн онлайн-користувачів, і під час пікових навантажень або техобслуговування (часто у вівторок) можливі збої.📩 Якщо Steam не працює навіть після стабілізації сервісів, тоді варто звернутися в Steam Support.✈️ Gamedev | [Джерело] | #новини #Steam #Downtime #Gaming #PC #SteamDown
🧐 Корутини & Task в C#Так. Почнемо з простого: чи всі взагалі знають різницю?Особисто я — людина, яка майже не використовувала Task, — ніколи їх навіть не порівнював і тим паче не замислювався, у чому ж між ними різниця.Давайте поясню:📱 Таски (Task) у C#: це асинхронні операції переважно реалізовані в рамках Task-based Asynchronous Pattern (TAP). Центральним класом є System.Threading.Tasks.Task, який «представляє одну операцію, що не повертає значення і зазвичай виконується асинхронно».Що це означає? Це спосіб запустити якусь роботу так, щоб програма не зависала і могла займатись іншими справами, поки ця робота виконується. Задачі (Tasks) зазвичай використовуються для виконання асинхронної роботи поза основним (UI) потоком, зокрема через пул потоків .NET.При використанні ключового слова async/await компілятор C# «перетворює ваш код у станoву машину». Це означає, що метод, який містить await, компілюється у спеціальний клас, що відстежує, де саме припинити виконання і як відновити його після завершення фонової операції. Також оператор await призупиняє виконання поточного методу та повертає керування його виклику, не блокуючи при цьому потік.📱 Coroutines в Unity використовують механізм yield return для очікування різних подій (наступного кадру, затримки через WaitForSeconds тощо). Unity щокадру перевіряє список активних корутин: якщо відбулася подія очікування (наприклад, минув час WaitForSeconds або настало наступне оновлення кадру після yield return null), відповідна корутина відновлює виконання. Таким чином корутина «розбиває» завдання на частини по кадрах, але завжди в межах основного потоку рушія.Не переживайте. Лінки на які не які документації я залишу 😅❓ Якщо підсумувати основні відміності:• Потоковий контекст: Задачі C# зазвичай працюють у фонових потоках, звільняючи основний потік для інших операцій. А Unity-корутини навпаки виконуються виключно на основному потоці рушія (ігровому циклі).• Механізм виконання: У C# асинхронний метод з await компілюється в станoву машину, яка «відслідковує виконання на await та продовжує його після завершення фонового завдання». Корутина ж реалізована через ітератор IEnumerator і генерує схожий механізм: під час компіляції C# утворюється клас, що зберігає поточний стан методу між yield-блоками.• Синхронізація та очікування: У TAP-методі C# очікування завершується подією/сигналом: коли фонове завдання виконується, воно «оповіщає» про свій стан, і тоді викликаються методи-продовжувачі (continuations). Це не вимагає постійного опитування як в Unity-корутинах, де перевірка відбувається щокадру.• Призначення та використання: а тут самі подумайте: хто з Вас використовував таски для якихось анімацій (чи для чого там ще потрібні корутини))?. Task призначені для будь-якого асинхронного програмування (мережевих запитів, паралельних обчислень тощо).ℹ️ Джерела: [Task.class] / [Asynchronous] / [await] / [Coroutines]Не знаю чи заходить вам такого роду контент, але сподіваюся, що так.Наступного разу, можливо, розкажу "що це за потоки" / Threads трішки детальніше 🔥✈️ Gamedev | #уроки #csharp #tasks #coroutines #unity #async #gamedev
📱 Unity знову може змінити правила гриБільшості, якщо не всіх, це не буде стосуватися. Тому не переживайте 😅Unity МОЖЕ запровадити нове щорічне мінімальне фінансове зобов’язання для клієнтів рівня Enterprise. Йдеться про суму від $250 000 до $2 000 000 на рік, яка буде прив’язана до валового доходу компанії за останні 12 місяців.Згідно з листом, який Unity розіслала клієнтам цього тижня, нововведення працюватиме в межах Unity Enterprise Minimum Commitment Program. Компанії, які за умовами ліцензії зобов’язані використовувати Enterprise, мають сплачувати мінімальну суму зобов’язання на початку кожного підписного року. Ці кошти зараховуватимуться в рахунок ліцензій та сервісів підтримки Unity.⚠️ За інформацією джерел, Unity також пригрозила відкликанням ліцензій у разі відмови від участі в програмі.
«Ми готові платити більше за ліцензію, але прив’язка плати до нашого доходу — це вже занадто. Це виглядає як шантаж», — коментує один із розробників.
📈 Нагадаємо, що з 12 січня 2026 року:• ціни на Unity Pro та Enterprise зростуть на 5%;• Havok Physics for Unity більше не входитиме до планів Pro, Enterprise та Industry.Після скандалу з Runtime Fee Unity обіцяла повернути довіру спільноти, однак нові кроки знову викликають питання: чи не перетворюється рушій на “податок з доходу” для розробників?✈️ Gamedev | #новини #Unity #gamedev
📱 Локалізація через CSV Всім привіт. Всі ж пам'ятають ось цей от асет? Якщо ні — раджу зазирнути, штука справді зручна 👀Ті, хто вже бачив, напевно пам’ятають обговорення про тексти підказок, які можна експортувати в CSV-таблицю. Так от, нещодавно розробники прокачали цю ідею й виклали окрему міні-систему локалізації текстів у вільний доступ.Звучить доволі круто, правда? 🔥❓ Про що взагалі мова?Мова йде про просту систему локалізації в Unity на базі CSV, яка підходить насамперед для інді-проєктів. Так, у Unity вже є офіційний Localization Package, який покриває майже всі кейси. Але інколи він здається надто важким або перевантаженим, особливо для невеликих ігор. Тому тут показано лайт-альтернативу з власними плюсами.⚙️ Як це влаштовано під капотом:🔹 CSV-таблиця з перекладамиВсі тексти гри зберігаються в одній CSV:• перший рядок — назви мов;• кожен рядок — один і той самий текст різними мовами.0 | Ukr | Eng | Jap1 | текст | text | 文章2 | меню | settings | 設定3 | ПКМ | RMB | 右クリック4 | гей | hello | こんにちは
🔹 ScriptableObject як “посередник”Вся логіка локалізації зосереджена в одному ScriptableObject, який зберігає CSV як TextAsset, один раз парсить таблицю на старті гри, пам’ятає поточну мову, віддає локалізовані рядки іншим скриптам і кешує текстові обʼєкти для автоматичного оновлення. Також це можна викликати з інших скриптів:InitializeLocalizator(); // На старті сесії один раз парсить CSV, згадує поточну мову, нехай "Ukr"GetStringText(2); // Повертає string з рядку 2 і стовпчику поточної мови = "меню"FillTextObject(2, textObj); // Передає в textObj.text = "меню"; кешує textObj і рядокChangeLanguage("Jap"); // Перезаписує поточну мову|--> TranslateAllTexts(); // Усім кешованим об'єктам замінює текст (той же рядок, інша колонка). //Те, що текстові об'єкти в кеші, дозволяє тут же міняти і їх шрифт, наприклад, якщо потрібні ієрогліфи*
*А тут згадаємо ще один пост: як бути, якщо CJK шрифти не відображаютьсяПоки ви сидите в шоці і думаєте наскільки це геніально, просто і круто - розкажу вам як це інтегрувати у свій проєкт:1. Заповнити таблицю своїми текстами і перекладами2. Де Start() > дописати виклик InitializeLocalizator3. Підв'язати метод ChangeLanguage до кнопок, що міняють мову4. При спавні тексту > викликати для нього FillTextObject, щоб він далі сам перекладався і міняв шрифт5. Якщо потрібно просто брати значення > викликати GetStringTextНадійніше вести стовпець в таблиці з текстовими ключами, щоб звертатись до рядків по ним, а не по індексам:using LocalizationSystemMini;[SerializeField] private InputStringsScriptableObject textStrings;var hi = textStrings.GetStringTextByKey("hi_key");var userName = "..."; // Ім`я гравцяtextObj.text = $"{hi}, {userName}!";// За потреби можна оновити шрифт вручну. Актуальний береться зі списку мова-шрифт, який розробник складає в скриптабл об'єктіtextObj.font = textStrings.GetCurrentFont();
Таким чином код буде мати доступ до локалізованого тексту, і виводити його на сцену.➕ Щоб додати мову й відредагувати переклади, достатньо відкрити CSV. Так можна перекласти цілий стовпець, пропустивши його через перекладач (або наш любимий ШІ). Або працювати з локалізаторами, у яких немає доступу/пристрасті до інспектора)🎁 В джерелі можна завантажити .unitypackage, взяти собі в проект готову структуру таблиці + скриптабла, одразу додати щось в CSV і спробувати викликати в коді. Система вже передбачає збреження мови між сесіями, підтримку шрифтів для різних мов і ще деякі цікаві фічі.Наприклад, переклади з плейсхолдерами {var}, розкиданими по тексту залежно від порядку слів у мові.А що ви думаєте про такого роду підхід? Або якому ви би надали перевагу?✈️ Gamedev | [Забрати] | #корисне #локалізація #переклад #localization
📱 Generics у C# (та Unity)Ось ми з вами говоримо часто про таку річ як Generic, але можливо хтось до кінця, або взагалі, не знає що це таке.Generics у C# – це можливість оголошувати класи, методи, інтерфейси тощо з узагальненими параметрами типу. Замість конкретного типу (наприклад int чи string) ви вказуєте параметр T, який задасться під час використання. Наприклад, .NET забезпечує багато generic-класів для колекцій (List<T>, Dictionary<TKey,TValue> тощо), адже вони можуть зберігати будь-який тип без втрати безпеки типів* (гарантія, що змінні та об’єкти у програмі працюють тільки з тими типами даних, для яких вони призначені, і не можуть бути випадково використані неправильно).📍 Синтаксис та створення власних generic-типівЩоб оголосити узагальнений клас або метод, використовують синтаксис з кутовими дужками <T>. Наприклад, узагальнений клас може виглядати так:public class GenericList<T>{ private List<T> innerList = new List<T>(); public void Add(T item) { innerList.Add(item); } public T Get(int index) { return innerList[index]; }}
У цьому прикладі T – параметр типу, він може бути будь-яким (вкладений у клас GenericList<T>). Коли ви створюєте список, передаєте конкретний тип: var intList = new GenericList<int>(); intList.Add(5);.Аналогічно можна писати generic-методи:public void Swap<T>(ref T a, ref T b) { T temp = a; a = b; b = temp;}
Тут метод Swap<T> може поміняти місцями будь-які два об’єкти одного типу. Виклик: Swap<int>(ref x, ref y).Якщо коротко то використовувати можна багато як. У тих же інтерфейсах і т.п. Але є ще одна цікава деталь!⛔️ Обмеження типів (where)Параметру T можна встановлювати обмеження (where-умови), щоб звузити, яким типом він може бути. Найпоширеніші обмеження:• where T : class – T повинен бути "посилальним" типом (неможна передати int тощо).• where T : struct – T повинен бути типом-значення (не клас).• where T : notnull – у контексті nullable вимоги – обмежує ненульовані типи (C# 8+).Думаю, логіка зрозуміла.Але якщо це канал про розробку ігор, то чому б і не згадати за практичне використання у нашому любимому Unity 😅📱 Використання generics у UnityUnity Scripting API містить багато generic-методів у своїй бібліотеці. Наприклад, GetComponent<T>() – це generic-метод у GameObject/Component, який повертає компонент типу T (де T : Component)Використання:Rigidbody rb = gameObject.GetComponent<Rigidbody>();
Цей виклик стає безпечним і не вимагає явного приведення типу.Ще один приклад – AddComponent<T>() – generic-метод GameObject.AddComponent<T>(), який додає компонент типу T до ігрового об’єкта. Сигнатура: public T AddComponent<T>()SphereCollider sc = gameObject.AddComponent<SphereCollider>();
Також гріх не згадати: UnityEvent<T> та Системи Entities (ECS).Ну і базові методи по типу FindObjectOfType<T>() / FindObjectsOfType<T>(), GetComponentInChildren<T>(), GetComponentInParent<T>(). Тобто, якщо ви не знали точно, що таке Generic, то ви 100% з ним стикались.⚠️ Звісно, хоча існують і нюанси, але краще прочитати самому, якщо це вам настільки цікаво.[Джерело 1] / [Джерело 2] / [Джерело 3].На жаль, саркастичного і влучного жарту не придумав. Не сьогодні...✈️ Gamedev | #уроки #Generic #csharp #unity