Решили: скины курсора собираются скриптом из векторных исходников пака Kenney, а их величина сводится по диагонали фигуры, а не по размеру холста.
Почему: просьба звучала как «заскейль ×10, как делали со спрайтами» — то есть про качество. Но у
этих курсоров вся форма построена на диагоналях, и растровый апскейл нейрестом зазубрил бы обводку;
у Kenney при этом лежит Vector/Outline/*.svg, откуда можно отрендерить сразу в целевое разрешение
без единой ступеньки. Отвергнут именно апскейл, не идея крупной текстуры: холст остался 320×320.
Вторая развилка — по чему равнять величину. Холст у всех исходников одинаковый (32×32) и потому
обманчив: фигура внутри разъезжается почти вдвое (pointer_a — 16×20, pointer_toon_a — 29×28).
Равнение по холсту дало бы набор, где один курсор жирный, другой тощий, и объяснить это глазом
было бы нечем.
Сказано: «Заскейли размер изначальных текстур х10 как делали со спрайтами для хорошего качества. Как хранить курсоры - реши сама, главное чтобы можно было посмотреть потом размеры все-всех курсоров и то, что они нормальные. Не слишком большие. Не слишком большие относительно друг друга.» (03.08.2026, сессия b307a49b). Способ изменён против буквы просьбы и назван вслух; требование «посмотреть размеры» закрыто замером, а не картинкой.
Грабли:
renderPMиз reportlab не умеет прозрачный фон — фон обязателен, и альфа теряется. Лечится двумя прогонами, на чёрном и на белом: разница целиком приходится на фон, отсюда альфа, а цвет восстанавливается делением. Нужен ещё backendrlPyCairo, без него рендер падает с «cannot import desired renderPM backend».- Остриё нельзя вывести из картинки. Направление у скинов разное — у
wedgeстрелка смотрит вправо-вниз, — поэтому «левый верхний непрозрачный пиксель» это не остриё вообще, а только для стрелок одного направления. Скрипт прижимает фигуру к углу холста, и тогда хотспот у скина — маленькое число (2–3% стороны), которое проверяется тестом, а не подбирается в инспекторе. - Скин обязан ехать по сети. Косметика, видимая только своему хозяину, косметикой не является —
поэтому
CursorSkinIdлежит в составе сеанса рядом с мейн-цветом, а не в локальных настройках. - Текстура обязана быть белой с чёрной обводкой. Цвет игрока накладывается тинтом (умножением): белая заливка становится мейн-цветом, обводка остаётся чёрной и держит курсор читаемым и на светлой карте, и на тёмной арене. Цветной скин красить было бы нечем — это условие набора, а не случайность.
Владелец правды: scripts/cursors-build.py, Data/Definitions/CursorSkinData.cs,
тест CursorSkinSizeTests.