Советы по форкам
Общий набор советов по форкам и согласованных лучших практик от разработчиков форков. Если вы разработчик форка и хотите что-то сюда добавить, пожалуйста, откройте PR.
Настоятельно рекомендуется иметь некоторый опыт работы с SS14 и RT, прежде чем создавать собственный форк.
Этот документ описывает только технические аспекты форкинга. Имейте в виду, что любому хорошему форку потребуется команда администраторов и правила.
Создание вашего репозитория
Не следует создавать репозиторий вашего проекта кнопкой форка на github. Это потому, что github разрешает только один форк репозитория на аккаунт, и форки вашего репозитория будут учитываться так же, как форки вашего upstream. Кроме того, когда у вас есть репозиторий, форкнутый кнопкой форка, очень легко по ошибке отправить изменения в ваш upstream.
Вместо этого сделайте следующее:
- Создайте пустой репозиторий, либо как организация, либо в вашем пользователе. Не инициализируйте репозиторий начальным коммитом; оставьте его пустым.
- git clone репозиторий upstream, от которого вы хотите форкнуться (если у вас уже есть локальная копия, можете использовать её вместо этого)
git remote add YourFork github.com/YourOrg/YourRepo, чтобы добавить ваш пустой репозиторий как remote- git checkout нужной ветки remote. Если вы основываетесь на Wizard’s den, настоятельно рекомендуется основывать ваш форк на stable.
git fetch upstream stable(при условии, что remote, указывающий на репозиторий, от которого вы хотите форкнуться, называется upstream)git checkout upstream/stable
git push YourFork master, чтобы отправить это в ваш форк как ветку master.
Поздравляем, вы успешно начали форк!
Чтобы обновить ваш форк в будущем, сделайте следующее:
- Создайте новую ветку на основе самого свежего коммита вашего форка
- git fetch нужной ветки upstream, как указано выше
- Затем git pull её.
Продолжая пример с mainline stable, команды, используемые для вышеописанного, были бы:
git fetch upstream stablegit pull upstream stable- Исправьте конфликты слияния при необходимости и создайте PR вашей свежей ветки слияния upstream
- Если вы не хотите какую-то функцию upstream, сейчас самое время откатить изменение с помощью
git revert
Учтите, что всем участникам вашего форка нужно будет нажать кнопку форка github на вашем репозитории, а не на upstream.
Лицензирование вашего форка
Информация, написанная в этом документе, не должна толковаться как юридическая консультация и не должна использоваться в качестве таковой.
УБЕДИТЕСЬ, ЧТО ВЫ ПРОЧИТАЛИ И ПОНЯЛИ ЛИЦЕНЗИЮ ВСЕХ ФАЙЛОВ В ВАШЕМ ФОРКЕ.
Если вы не очень хорошо разбираетесь в лицензиях open-source, мы рекомендуем лицензировать ваш форк под той же лицензией, что и ваш upstream. Это создаст вам наименьшее количество юридических проблем (или, скорее, общей полемики). Wizard’s Den использует “MIT License” (которую иногда называют лицензией Expat). Копия этой лицензии уже включена в репозиторий и не требует никаких действий с вашей стороны для использования. Лицензия MIT даёт вам право делать с кодом почти всё что угодно (включая сублицензирование), если сохраняется копия уведомления об авторских правах.
Художественные ассеты в своём большинстве лицензированы исключительно под CC BY-SA 3.0 или CC BY-NC-SA 3.0. Для последней NC означает ‘non-commercial’ (некоммерческая): следовательно, любые ассеты, лицензированные под ней, не могут использоваться в коммерческих проектах; вам придётся либо удалить ассеты, либо попросить владельца перелицензировать их с разрешением коммерческого использования.
Имейте в виду, что при переносе контента из других форков у них могут быть более ограничительные лицензии, такие как GNU Affero General Public License (AGPL) или Mozilla Public License (MPL). Будьте осторожны, чтобы соблюдать ограничения, налагаемые этими лицензиями.
Лицензии AGPL и MPL являются лицензиями “copyleft”, то есть они требуют, чтобы любые модификации вашего кода выпускались под той же лицензией. AGPL требует, чтобы итоговый бинарник вашего проекта был лицензирован под AGPL, что означает, что каждый пользователь имеет право на копию всего дерева исходников. Это не позволяет вам иметь скрытый контент. Код AGPL может быть лицензирован двумя разными способами: AGPL-3.0-only или AGPL-3.0-or-later. Разница между ними в том, что код AGPL-3.0-or-later будет лицензирован под любой будущей версией AGPL, которую опубликует Free Software Foundation. У MPL нет опции “только v2”, ваша лицензия всегда будет последней версией, опубликованной Mozilla.
MPL требует только, чтобы файлы под лицензией MPL были предоставлены пользователям, что делает её подходящей для проектов, включающих скрытый контент. Учтите, что MPL имеет необязательный пункт под названием “Exhibit B”. Код, лицензированный под MPL с пунктом Exhibit B, не может быть объединён с кодом, лицензированным под AGPL.
Помните, что этот документ даёт лишь очень краткий обзор обсуждаемых лицензий. Вам следует прочитать лицензию любых файлов/кода, которые вы намереваетесь включить, целиком и проконсультироваться с юристом, если у вас есть вопросы.
Организация
Помещайте свой код в выделенные папки сервера.
Настоятельно рекомендуемый подход - помещать код вашего сервера (вместе с необязательным, но рекомендуемым файлом LICENSE, содержащим лицензию на ваш код) в собственную папку верхнего уровня внутри основных разделов кодовой базы.
Например, во всех папках Content.* была бы папка _ServerNameHere, в которую помещался бы весь код, специфичный для вашего сервера. Избегайте смешивания собственного кода с кодом upstream в этом отношении, чтобы избежать потенциальных конфликтов слияния в будущем.
Пространства имён для ваших компонентов (и любых других сериализуемых типов)
Все сериализуемые типы находятся в одном глобальном пространстве имён. Чтобы предотвратить конфликты, вам следует добавлять к ним префикс - короткий идентификатор вашего форка. Например, если ваш сервер назывался “Foo Bar”, вы могли бы добавлять ко всем компонентам префикс “FB”. Желательно держать его коротким, потому что вам придётся набирать его уйму раз.
Пространства имён для ваших прототипов
Аналогично пространствам имён для сериализуемых типов, прототипы также используют единое глобальное пространство имён. Настоятельно рассмотрите возможность давать всем именам прототипов префикс, чтобы избежать конфликтов. Например, можно дать сущности ID FooMyEntity вместо MyEntity, если сокращённое обозначение вашего сервера было “foo”.
Конфликты слияния не такие уж страшные.
Короче говоря, при изменении существующего кода методы избегания конфликтов в целом являются плохой практикой, поскольку они часто позволяют вашему коду продолжать компилироваться ценой того, что он больше не работает корректно. В целом, если у вас возникает конфликт слияния, скорее всего, он не беспричинен, и вам следует просмотреть его вручную, вместо того чтобы пытаться применить методы избегания.
Хотя это по большей части верно, избегание конфликтов, скажем, в списках элементов, в целом хорошая идея (поскольку они будут конфликтовать без необходимости чаще, чем нет.) Обычно это так же просто, как поместить ваши записи в начало списка или в отдельную часть списка, отделённую пробелами.
При изменении кода upstream рекомендуется оставить короткий комментарий, объясняющий почему было сделано изменение, чтобы облегчить слияния с upstream. Примером может служить // FOOFORK: изменено Bar на 2 вместо 1, потому что всё ломается, если стоит 1.
Избегание проблем в общих перечислениях.
Ярким примером этого является перечисление AdminLog, содержащее все виды админ-логов. Выберите узнаваемый десятичный (или шестнадцатеричный) префикс, положительный или отрицательный, для ваших значений и придерживайтесь его. В идеале выберите его случайно, чтобы у вас не было проблем со слиянием изменений других форков, если вы захотите сделать cherry pick.
CVar
Пространства имён для ваших CVar!
CVar могут быть вложены на столько уровней таблиц, на сколько захотите, например foo.respawn.time - допустимый ключ CVar, который соответствовал бы следующему:
[foo.respawn]
time = 360
Это помогает устранить неоднозначность в том, откуда взялся CVar. Кроме того, рассмотрите перенос любых CVar, в поведение которых вы вносите значительные изменения (скажем, добавление новых раскладок UI или изменение ключей перечисления), в ваш префикс.
Используйте собственные CVarDefs вместо CCVars
Мастер-класс CCVars является некоторым антипаттерном даже в upstream. Вы можете объявлять новые классы CVarDef где угодно и размещать свои CVar там, а не в CCVars.
Например:
[CVarDefs]
public static class MySubsystemCVars
{
/// <summary>
/// Это мой CVar!
/// </summary>
public readonly static CVarDef<bool> MyCVar = CVarDef.Create("foofork.subtable.mycvar", false);
}
Может быть целесообразно иметь CVarDefs на каждую крупную подсистему, например, вы бы поместили cvars генерации мира в ту же папку, что и сам код worldgen. Имя статического класса не имеет значения.
Вы можете поместить класс CVarDefs только в клиент или только в сервер, но учтите, что это приведёт к тому, что CVar будет залогирован как отсутствующий, если он окажется в файле конфигурации, загружаемом обеими сторонами.
ДА, редактируйте значения по умолчанию в коде!
Скорее всего, вас будет соблазнять изменить или ввести предустановку конфигурации, чтобы изменить значения по умолчанию CCVars без редактирования самого класса. Это в некоторой степени согласуется с Конфликты слияния не такие уж страшные., делая так, вы открываете себя для изменения upstream значения по умолчанию значимым образом (например, изменение того, что на самом деле представляет собой число, например минут на секунды или наоборот.) и застреваете с багом в продакшене, если это останется незамеченным.
Конфликты пытаются сказать вам что-то, если они возникают.
Но не делайте значения по умолчанию специфичными для сервера.
CCVars - это не файл конфигурации вашего сервера, настраивайте свой сервер на своём сервере в server_config.toml, а не в кодовой базе. Меняйте значения по умолчанию, если значение по умолчанию ломает игру, включает механики, которые вы хотите отключить, или ломает ваш дизайн, а не для того, чтобы задать ссылку на ваш discord.
Схема базы данных
EFCore на самом деле не предназначен для использования так, как вы будете его использовать в качестве разработчика форка; если вы можете избежать изменений в БД, вам следует это сделать. Чтобы избежать ряда багов (в первую очередь этого), настоятельно рекомендуется не изменять таблицы вашего upstream. Вместо этого вам следует создать соответствующую таблицу для данных вашего форка, находящуюся в отношении один к одному с исходной таблицей.
Любые миграции, которые вы добавляете, должны иметь пространство имён таким же образом, как прототипы и компоненты. Хотя вероятность коллизии миграций практически отсутствует, это делает ясным, какие миграции были добавлены вашим форком.
Наконец, убедитесь, что вы протестировали свои изменения и миграции как на postgres, так и на sqlite, чтобы избежать потери данных. Не забывайте регулярно делать резервные копии вашей базы данных.