---
title: "Ассеты: где брать и лицензии"
description: "Бесплатные спрайт-паки, шрифты, звуки, лицензии: где брать игровые ассеты честно. CC0, CC-BY, CC-BY-SA, embed и титры: что обязан сделать разработчик."
course: "Ebitengine: 2D-игры на Go"
url: "https://golangmaster.ru/courses/ebitengine/lessons/23-assety-i-lisenzii/"
published: "2026-09-19"
updated: "2026-09-21"
minutes: 16
---

# Ассеты: где брать и лицензии

*Курс «Ebitengine: 2D-игры на Go», урок 23 из 25. ~16 минут. Обновлено 21.09.2026. Источник: https://golangmaster.ru/courses/ebitengine/lessons/23-assety-i-lisenzii/*

Игра почти собрана, но выглядит как техническая демка: игровые ассеты — спрайты, шрифты, звуки — пока не пришли из чужих рук, а вместе с ними не пришли и чужие условия использования. Разберём, где брать ассеты бесплатно и честно, как читать CC0, CC-BY и CC-BY-SA и чем они отличаются на практике, как упаковать папку assets в бинарник через go:embed и зачем проекту файл титров CREDITS.md со строкой на каждый ресурс.

Ни один движок не поставляется с героем: картинки, шрифты и звуки в игру приносит разработчик, и берёт их из двух источников — рисует сам или берёт готовое. Рисовать самому долго и не обязательно, а готовое несёт с собой чужие условия: у каждого файла есть автор и лицензия, и они не отменяются копированием в проект. Отсюда три вопроса урока: где искать паки, что именно разрешает лицензия и что вы обязаны сделать в ответ — указать автора, сохранить копию лицензии или просто взять и молчать. Игровые ассеты — единственная часть курса, где главная работа происходит не в редакторе кода, а в текстовом файле LICENSE, и это тоже инженерный навык: релизная игра — это код плюс честно оформленные заимствования. Правовая часть пугает сильнее указателей, но объём у неё скромный: пять обозначений — CC0, CC-BY, CC-BY-SA, OFL и NC — покрывают почти весь рынок бесплатных ассетов, а исполняются условия одним файлом титров и дисциплиной коммитов. Остальное — организация: папка assets, директива embed и загрузчик, возвращающий понятные ошибки.

### Карты источников: где живут бесплатные ассеты

Начните с мест, где лицензии организованы честно. Kenney.nl — библиотека из тысяч паков: двухмерные спрайты, тайлсеты, UI-наборы, звуки — всё под CC0, то есть в общественном достоянии: брать можно без спроса, менять как угодно и продавать игру без отчислений и даже без упоминания автора. OpenGameArt — агрегат, где у каждого ресурса своя карточка: CC0, CC-BY или CC-BY-SA, и читать надо страницу конкретного пака, а не правила сайта. Раздел game assets на itch.io полон бесплатных материалов, но «free» говорит только о цене: лицензия у каждого пака своя, от щедрой до запретительной.

Шрифты ищите на Google Fonts: большинство семейств живут под OFL, которая прямо разрешает встраивание в приложения и игры. Звуки — Freesound, где лицензия назначается клипу отдельно, и рядом с честным CC0 соседствует неудобный CC-BY-NC. Отдельная категория — процедурные генераторы sfxr, jsfxr и Bfxr: сгенерированный звук ничей — он ваш с первой секунды. Общее правило: источник — витрина, лицензия живёт у конкретного файла. Держите карту в закладках и пополняйте по мере проектов: проверенный источник экономит час поиска в следующей игре, а привычка смотреть лицензию до скачивания превращается в рефлекс, который дальше работает сам.

### Спрайт из встроенной папки

```go
package main

import (
        "embed"

        "github.com/hajimehoshi/ebiten/v2/ebitenutil"
)

//go:embed assets/*
var assetsFS embed.FS

func loadPlayer() (*ebiten.Image, error) {
        img, _, err := ebitenutil.NewImageFromFileSystem(assetsFS, "assets/player.png")
        if err != nil {
                return nil, err
        }
        return img, nil
}
```

Директива go:embed над переменной embed.FS пакует папку assets внутрь бинарника при компиляции: файловая система перестаёт быть внешним миром и едет вместе с игрой. assetsFS реализует стандартный интерфейс fs.FS, а NewImageFromFileSystem открывает путь и декодирует PNG в ebiten.Image — тот же тип, что рисовал спрайты раньше, только источник теперь встроенный и одинаковый на всех платформах. Ошибка возвращается наверх без проглатывания: вызывающий код решает сам, падать целиком или рисовать заглушку.

**Вопрос:** В проект попал спрайт-пак под CC-BY. Что лицензия обязывает сделать?

- Удалить файл лицензии: ассет уже скачан и ничего не должен
- ✅ Указать автора, источник и лицензию в доступных титрах
- Написать автору и дождаться письменного разрешения
- Ничего: CC-BY совпадает с CC0 по условиям

CC-BY — лицензия с единственным условием: атрибуция. Автору не платят и разрешения не спрашивают, но имена обязаны быть названы в доступном месте — обычно в титрах. Остальные варианты либо противоречат условию, либо описывают CC0, у которого обязательств нет вовсе.

### Читать лицензию: CC0, CC-BY и CC-BY-SA

Creative Commons выглядит как один значок, а требует разного. CC0 — автор отказался от прав целиком: условий нет, атрибуция не нужна, менять и продавать можно; единственная лицензия, которая не создаёт обязательств. CC-BY добавляет одно условие — атрибуцию: доступное место — обычно титры игры — должно назвать автора, источник и лицензию. Обязанность не истекает с релизом: она живёт столько, сколько живёт игра.

CC-BY-SA добавляет пункт ShareAlike: производные работы обязаны распространяться под той же лицензией. Для открытого проекта это естественно, для закрытой игры — риск: в спорных трактовках производной оказывается вся игра целиком. Отдельно запомните NC: «некоммерческое использование» разом отсекает платный магазин, рекламу и платные версии; формулировка «free for non-commercial» — та же ловушка другими словами. Рабочее правило: лицензия не прочиталась за минуту — файл не берётся, а поиск продолжается с фильтром CC0; во всех источниках выше такой фильтр есть. Ещё одна деталь, о которую спотыкаются: у пака и у отдельного файла из него условия бывают разными, как и у ремикса чужого ресурса — читается не «что написал сайт», а что написано рядом с конкретным файлом.

### Загрузчик: один вход для всех картинок

```go
type Assets struct {
        Player  *ebiten.Image
        Enemy   *ebiten.Image
        Tileset *ebiten.Image
}

func LoadAssets() (Assets, error) {
        var a Assets
        var err error

        a.Player, _, err = ebitenutil.NewImageFromFileSystem(assetsFS, "assets/player.png")
        if err != nil {
                return a, fmt.Errorf("player: %w", err)
        }
        a.Enemy, _, err = ebitenutil.NewImageFromFileSystem(assetsFS, "assets/enemy.png")
        if err != nil {
                return a, fmt.Errorf("enemy: %w", err)
        }
        a.Tileset, _, err = ebitenutil.NewImageFromFileSystem(assetsFS, "assets/tileset.png")
        if err != nil {
                return a, fmt.Errorf("tileset: %w", err)
        }
        return a, nil
}
```

Один вход для всех картинок: структура Assets хранит готовые ebiten.Image, а LoadAssets возвращает ошибку с именем ресурса — при опечатке в пути вы сразу увидите, какой файл не встроился. Game получает весь набор один раз на старте, и ни одна сцена не ходит к файлам сама. Порядок загрузки фиксирован, и игра до завершения LoadAssets просто не начинается. Шрифты и звуки подключаются тем же способом: из того же embed.FS, через текстовый и аудио-механизмы курса.

### Ресурс, лицензия и обязанность разработчика

| Ресурс | Лицензия | Что обязан сделать разработчик |
| --- | --- | --- |
| Паки Kenney.nl | CC0 | ничего: атрибуция не требуется, продажа разрешена |
| Пак с OpenGameArt | CC-BY | титры: автор, источник, название лицензии |
| Тайлсет CC-BY-SA | CC-BY-SA | титры плюс производное под той же лицензией — риск для закрытой игры |
| Пак «free» с itch.io | у каждого своя | прочитать LICENSE до скачивания и действовать по нему |
| Шрифт с Google Fonts | OFL | копия лицензии рядом с файлом; сам шрифт не продавать |
| Клип Freesound с пометкой NC | CC-BY-NC | титры и никакого платного использования — не для коммерции |

### Что вернёт путь без префикса assets?

```go
//go:embed assets/*
var assetsFS embed.FS

img, _, err := ebitenutil.NewImageFromFileSystem(
        assetsFS, "player.png",
)
```

**Что выведет программа?**

- Спрайт загрузится: embed ищет файлы по всей папке проекта
- ✅ Ошибка при запуске: в embed.FS пути сохраняют префикс assets/
- Ошибка компиляции: пути ассетов проверяются на этапе сборки
- Пустая картинка: файл не найден, но err останется nil

Пути внутри embed.FS начинаются с имени встроенной папки: файл лежит как assets/player.png, и запрос player.png не найдётся. Ошибка придет во время выполнения — на этапе сборки проверяется совпадение шаблона с файлами на диске, но не каждый путь в коде. Правило: путь внутри FS пишется так, как файл лежит в репозитории.

### Папка assets и go:embed: от файла к бинарнику

Папка assets — единственный источник ассетов, который вы контролируете целиком: скачанные PNG, шрифты и звуки складываются туда, и дальше с ними работает только компилятор. Директива go:embed встраивает файлы в бинарник на этапе сборки, и это не стилистическое предпочтение: после урока про [сборку на платформы](/courses/ebitengine/lessons/22-sborka-platformy/) вы знаете, что у WASM и мобильных версий нет доступа к вашей локальной файловой системе — относительный путь через обычный os.Open там не найдёт ничего. Встроенный FS ведёт себя одинаково на всех платформах.

Нюанса два. Первый: файлы, чьи имена начинаются с точки или подчёркивания, в бинарник не попадают — держите имена чистыми. Второй: пути внутри embed.FS сохраняют префикс assets, и запрос без него не найдёт файл — ошибка новичка номер один. Третий практический пункт — размер: встроенные файлы увеличивают бинарь на свой вес, поэтому тяжёлые видео и сотни мегабайт аудио туда не кладут; для игр курса паков хватает с запасом. Структуру папки ведите плоско или с понятными подпапками: это продолжение [структуры проекта](/courses/ebitengine/lessons/21-struktura-proekta/), а не свалка для скачанного.

**Вопрос:** Чем CC0 отличается от CC-BY с точки зрения разработчика игры?

- CC0 запрещает продажу игры, CC-BY разрешает
- ✅ CC0 не требует упоминания автора, CC-BY требует атрибуции
- CC0 действует только на графику, CC-BY — на любые файлы
- Разницы нет: это два названия одного и того же

CC0 не создаёт обязательств вовсе: автора указывать не требуется. CC-BY добавляет ровно одно требование — атрибуцию, и это единственная разница, влияющая на релиз: забытые титры превращают законное использование в нарушение, а продающую игру CC-BY разрешает так же, как CC0.

> **Живое место: CC-BY-SA и закрытая игра.** Типовая история: в игру заходит красивый тайлсет CC-BY-SA с OpenGameArt, игра собирается и уезжает в платный магазин — а пункт ShareAlike требует распространять производные работы на тех же условиях. Граница производного для ассетов внутри проприетарной игры размыта, и спорить придётся не с движком, а с автором. Что сломалось бы дальше: либо проект открывает изменённые ассеты, либо автор требует удалить контент из продажи. Правило для закрытых релизов: CC0 и CC-BY — да, SA и NC — нет, пока вы не готовы делиться или не купили отдельную лицензию у автора. Вторая половина ловушки — обновления: новая версия пака может выйти под другой лицензией, и честно скачанный файл заменяется файлом с новыми условиями; дата в строке CREDITS.md покажет, какая версия была в игре.

### Титры: CREDITS.md как часть проекта

Атрибуция исполняется не намерением, а файлом. Заведите CREDITS.md в корне рядом с assets и добавляйте строку в тот же коммит, что и сам ассет: название ресурса, автор, источник, лицензия, дата. Строка выглядит так: «Ninja Sprite Pack — Kenney, kenney.nl, CC0, 2024». Для CC0 это вежливость и аудит — при обновлении пака вы вспомните, откуда файл; для CC-BY — прямое исполнение лицензии, записанное до того, как память подвела.

Титры дублируются в саму игру: пункт «Credits» в [сцене меню](/courses/ebitengine/lessons/15-sceny/) — такой же элемент интерфейса, как пауза, потому что игрок должен иметь возможность увидеть имена. Данные читаются из того же списка: CREDITS.md служит и игроку, и разработчику одновременно. Перед релизом сверьте направления: каждый файл из assets/ упомянут, у каждой строки есть живой файл; расхождение в любую сторону — либо неоплаченный долг лицензии, либо мусор в репозитории. Имя файла не случайно: markdown читается в diff, на хостинге репозитория и в телефоне, а простой текст переживёт любой рефакторинг — таблица в редакторе документов таких гарантий не даёт.

### Чек-лист принятия ассета в проект

- Лицензия прочитана у конкретного пака, а не на главной странице источника
- Тип лицензии назван словами: CC0, CC-BY, CC-BY-SA, OFL или своё условие
- Для CC-BY записаны автор, источник и версия лицензии
- NC-варианты отсеяны, если игра когда-нибудь будет продаваться
- Файл лёг в assets/ без точки или подчёркивания в начале имени
- Строка в CREDITS.md добавлена тем же коммитом, что и файл
- Пункт титров в игре обновлён вместе с ассетом
- Непонятная лицензия означает поиск замены, а не обещание разобраться потом

### Соберите объявление встроенных файлов

Восстановите два пропуска: имя пакета и тип встроенной файловой системы.

```go
import (
        "___"
)

//go:embed assets/*
var assetsFS embed.___
```

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

Правильные ответы в пропусках: `embed`, `FS`

> **Про песочницу: ассеты без локальных файлов.** В песочнице сайта нет файловой системы проекта и директивы go:embed — код этого урока запускается только в локальном Go. Зато чтение лицензий, заведение CREDITS.md и выбор источников работают без компилятора, а место героя до первой настоящей картинки в песочнице занимает прямоугольник из примитивов: заглушка честнее отсутствующей картинки. Полный путь ассета отрабатывайте в своём окружении, а переносить имеет смысл то, что не зависит от файлов: шаблон строки титров и порядок шагов чек-листа.

### Путь ассета: от скачивания до экрана

Расставьте шаги от пакета до работающего спрайта.

Правильный порядок строк:

1. `Скачайте пак и распакуйте во временную папку`
2. `Прочитайте LICENSE рядом с файлами, а не описание на сайте`
3. `Скопируйте нужные PNG в assets/ проекта`
4. `Добавьте строку ресурса в CREDITS.md`
5. `Объявите //go:embed assets/* над переменной embed.FS`
6. `Загрузите спрайт через NewImageFromFileSystem`
7. `Соберите бинарь и проверьте картинку на экране`

### Шрифты и звуки: отдельные правила

Шрифты живут по своим законам: Google Fonts раздаёт большинство семейств под OFL — встраивать в игру можно и нужно, копию лицензии держите рядом с файлом шрифта, а продавать сам шрифт нельзя. Механика отрисовки текста уже готова из урока про шрифты — меняется только источник, а текстовый рисующий код не замечает подмены.

Звуки дисциплинируют сильнее графики: на Freesound лицензия назначается клипу, поэтому фильтр CC0 ставьте до прослушивания — иначе через час поиска никто не вспомнит, какой клип был под каким условием. NC-варианты отметайте сразу, если игра когда-нибудь окажется платной. Альтернатива без правовых вопросов — генераторы sfxr и Bfxr: ползунки, кнопка экспорта, и результат полностью ваш; выстрелы, прыжки и подбор монет генерируются за минуты и встают в [аудио-систему](/courses/ebitengine/lessons/18-zvuk/) как обычные файлы, встроенные тем же go:embed. Отдельный совет про музыку: треки ищите по тем же правилам, что и эффекты, только цена ошибки выше — фоновый трек слышен весь сеанс и именно его чаще всего забывают в титрах.

К концу урока у проекта появляется материальная часть: папка assets с честными лицензиями, встроенная в бинарник директивой go:embed, загрузчик, возвращающий готовые спрайты, и CREDITS.md, где у каждого ресурса есть строка. Это закрывает последний инфраструктурный вопрос перед содержательным: впереди гейм-дизайн с балансом и итоговый проект, где всё соберётся в одну аркаду. Домашнее задание проводит первый ассет по полному пути — от страницы источника до экрана и титров. И держите рядом правило проверки: непонятная лицензия — это не обещание разобраться потом, а немедленный поиск замены под CC0; в релизной сборке репутация живёт в тех же файлах, что и игра. Дисциплина переносится и вне игр: любой проект с чужими зависимостями — от иконок до библиотек — живёт по тем же правилам чтения лицензий.

### Термины урока

- **CC0** — Автор отказался от авторских прав полностью: условий нет, атрибуция не требуется, коммерческое использование разрешено.
- **CC-BY** — Лицензия с одним условием — атрибуцией: в титрах указываются автор, источник и лицензия. Продажа игры разрешена.
- **CC-BY-SA** — CC-BY плюс ShareAlike: производные работы — под той же лицензией. Опасно для закрытых коммерческих игр.
- **go:embed** — Директива компилятора, встраивающая файлы в бинарник; переменная embed.FS работает как обычный fs.FS на всех платформах.
- **CREDITS.md** — Файл титров проекта: ресурс, автор, источник, лицензия, дата. Исполняет атрибуцию CC-BY и держит аудит ассетов.
- **OFL** — Свободная лицензия шрифтов: встраивание в игры разрешено, продажа самого файла шрифта — нет.

## Коротко: что запомнить

- Источник — витрина; лицензия живёт у конкретного пака: CC0, CC-BY, CC-BY-SA, OFL или своё условие.
- CC0 не требует ничего; CC-BY требует атрибуции; SA и NC опасны для закрытых коммерческих игр.
- Папка assets плюс go:embed пакует ассеты в бинарник и одинаково работает на всех платформах сборки.
- Пути внутри embed.FS сохраняют префикс assets; файлы с точкой или подчёркиванием в имени не встраиваются.
- Один загрузчик возвращает готовые ebiten.Image и честную ошибку с именем файла.
- CREDITS.md в корне и пункт титров в меню — исполнение атрибуции и часть релиза.
- Непонятная лицензия означает немедленный поиск замены под CC0, а не обещание разобраться потом.

## Домашнее задание

Соберите первую партию ассетов по чек-листу урока. Скачайте два пака Kenney и один CC-BY-пак с OpenGameArt; создайте папку assets и CREDITS.md, внеся строку для каждого ресурса в момент скачивания. Подключите go:embed и замените прямоугольник героя на спрайт из урока про спрайты — загрузку оформите через LoadAssets с проверкой ошибок и понятными сообщениями. Добавьте в меню пункт «Credits» и выведите титры на экран в сцене из урока про сцены. Соберите бинарь и WASM-версию из урока про сборку: на встроенных ассетах обе должны запуститься одинаково. Найдите на Freesound один CC0-звук и один NC — второй не подключайте, а запишите в заметку, почему нельзя. В конце проверьте, что файлы с точкой или подчёркиванием в начале имени не попали в assets: embed их молча пропустит. Финальная проверка — запустить бинарь из другой папки: встроенные ассеты обязаны загрузиться без зависимости от текущей директории, потому что едут внутри бинарника.

## Вопросы и ответы по уроку

### Можно ли брать ассеты из Unity Asset Store или Figma Community в игру на Ebitengine?

Каждый магазин пишет свои условия, и они не привязаны к движку напрямую, но часто ограничивают рантайм или требуют упоминания магазина. Правило то же: читать лицензию конкретного пака до скачивания. Универсальные CC0-источники дешевле по вниманию: условия знакомые и короткие, а если сомнение осталось — пишите автору: молчаливое «наверное можно» в релизе хуже отказа.

### Kenney просит указывать себя? Пак ведь CC0.

Не просит: CC0 снимает обязанность атрибуции. Строка в CREDITS.md остаётся хорошей практикой — при обновлении пака вы вспомните, откуда взяли файл, а не будете искать источник по названию спрайта через полгода. Та же строка — публичное уважение к чужому труду: авторы видят использование и продолжают делиться.

### Ассет уже в игре, а лицензия нашлась позже — что делать?

Прочитать её спокойно. Если условия исполняются — дописать CREDITS.md и жить дальше. Если нет — NC в платной игре или SA в закрытом проекте — заменить ассет и вычистить файл из релиза; замена через загрузчик урока — правка одной строки пути, остальной код подмену не замечает.
