Log of Alprog
1.19K subscribers
98 photos
91 links
加入频道
А я начинаю серию технических постов про архитектуру и графику игры. Казалось бы, ну чего там может быть интересного в программировании RPG с пошаговой боёвкой? Тем более на Unity (читай — на всём готовом). А вот оказывается, что кое-что может. На несколько постов точно уж наберётся. Понимаю, что не все мои читатели программисты, поэтому буду маркировать посты, затрагивающие эту тему, хештегами #код или #кодище (в зависимости от интенсивности). Лайтовые посты на общие темы буду помечать тегом #лайт.
Скрипты в Encased
#код
Формально весь код, который мы пишем для Encased — это C# скрипты (в исходники Unity мы не лезем). Но у нас есть два уровня скриптов: механика игры, которую пишут программисты; и «скрипты скриптов», которыми занимаются контент-мейкеры, то есть гейм- и левелдизайнеры. В первую очередь, это сценарии квестов. Чтобы как-то различать, но не изобретать новую терминологию, в рамках компании мы код программистов скриптами не считаем. Это условно просто код игры. А слово «скрипт» применяем только для скриптинга квестов и локаций. Именно о них сейчас и пойдёт речь.

Вообще, я большой и страстный фанат lua. Связку Сpp + lua и вовсе считаю идеальной для геймдева. Господи, у меня об этой парочке даже любовная лирика есть — настолько всё плохо :) Но так или иначе, поскольку мы пишем на Unity, то у нас уже есть связка Cpp + C#. Да, некоторые прикручивают lua к Unity, но обычно это те же самые люди, которые высказываются в духе «C# теснит C++ в геймдеве». То есть в их голове получившаяся схема выглядит, как C# + lua, но на самом-то деле это Сpp + C# + lua. Лично мне, как стороннику принципа KISS, от такой переголовы становится плохо. Каждый понимает этот принцип по-своему (об этом как-нибудь в другой раз), но для меня это означает, что в проекте должно быть как можно меньше лишних сущностей, а, значит, в качестве языка для скриптов мы остановимся на идущем из коробки C#.

С языком определились, осталось эти скрипты спроектировать. И здесь мне очень сильно повезло: в нашей команде есть дизайнеры, которые работали над похожей по механикам и масштабу игрой — над Divinity: Original Sin 2. Поэтому мне не нужно гадать, что им может понадобится, а что — нет; мне достаточно посмотреть все их юзкейсы, скопившиеся за время работы над игрой, и просто реализовать привычный для них функционал. Там y них был свой собственный язык сценариев, я же попробовал адаптировать это к C# и нашей архитектуре, и получилось примерно следующее.

Каждый скрипт (например, квест) — это отдельный класс, унаследованный от класса Script. Каждый скрипт может существовать в проекте только в одном экземпляре. У него есть функция Start() и во включённом состоянии у него выполняется Update(deltaTime). Скрипт может находить игровые сущности в мире (сущности у нас отвязаны от сцен и GameObject’ов и доступны из кода всегда, даже если игрок сейчас в другой локации), назначать этим сущностям задачи в очередь выполнения и подписываться на их эвенты.

Система эвентов представляет собой надстройку на основе делегатов. Можно подписываться, как на события от конкретной сущности, так и глобально на все события определённого типа. Во втором случае можно также добавить подписке фильтры. Например, подписаться на клики по объектам с определённым тегом. Обработчик события при сохранении резолвится в имя скрипта и метода. Да, для совместимости сейвов переименовывать методы нельзя. Во всём остальном проекте их можно переименовывать, потому что они помечаются атрибутами сериализации; но в скриптах решили атрибуцию не делать, чтобы их не усложнять (скриптеры готовы мириться с таким ограничением, а если уж очень надо, то рулить версионность ифами). Также в классе скрипта сериализуются и попадают в сейв все его поля. Для разработчика скрипта это получаются своего рода локальные переменные, где он может хранить всякие временные штуки.

Вот такая примерно система у нас. На мой взгляд, получилось довольно гибко и удобно. Так ли это на самом деле покажет время, когда мы перейдём в фазу активного наполнения игры контентом (пока у нас основная механика и даже архитектура ещё в процессе). Буду держать вас в курсе.
Jai vs C++
#код
На днях все снова заговорили про язык Jai, в связи с новостью о том, что его автор, Джонатан Блоу, собирается выпустить закрытую бету до конца года. Я решил, что дети могут насмотреться его стримов и неправильно понять, и что кто-то из взрослых должен объяснять такие вещи. Не думаю, что в русскоязычном геймдев сообществе наберётся много авторов, которые могут писать про такие темы, поэтому почему бы мне не стать таким человеком?

Начнём с того, что Блоу (это автор Braid и The Witness, если кто не в курсе) один из немногих в индустрии, на которых действительно хочется равняться. Из всех инди-разработчиков его философия и подходы наиболее близки мне. Во-первых, он относится к играм, как к искусству. И здесь я имею в виду, что он стремится, чтобы они таковыми были, но при этом не переоценивает их нынешнюю ценность (включая свои проекты). И, во-вторых, насколько я могу судить, считает написание кода не препятствием на пути чистого творчества, а частью этого самого творчества. Техническое исполнение это не просто средство, это часть самого произведения искусства. Если вы думаете сходным образом, вы поймёте, что красота должна быть везде: и в геймдизайне, и в коде. Они должны дополнять друг друга, работать в ансамбле; одно ради другого страдать не должно. Отсюда и тяга и к написанию идеальных инструментов под себя: чтобы творить в удовольствие, а не идти каждый день на компромисс с самим собой. В этом мы с ним похожи. Только он версия на максималках. Вернее HD ремастер на максималках.

Я пишу движок, чтобы в будущем комфортно было заниматься своими проектами; у Блоу уже есть два мировых хита и он идёт дальше — пишет для себя свой язык, и ничего, кроме уважения, это у меня не вызывает. Но как только кто-то начинает говорить (в первую очередь сам Джонатан), что Jai способен заменить С++ у широкой аудитории (и тем более в ААА), вот тут-то у меня и начинается скепсис. Сколько уже было попыток: D, Go, Rust? По моему мнению, Jai просто пополнит этот список.

Само желание избежать C++, мне понятно. Он причиняет боль, и я бегал от него по всяким бейсикам и шарпам до последнего, так как верил, что их мне хватит. Но чем дольше прятался, тем очевиднее становилось, что мне не хватает производительности и трушной кроссплатформенности. Какой-нибудь маленький инди-проект, конечно, можно написать на D или Rust, но если ты пишешь движок, который собираешься в дальнейшем поддерживать, или если ты большая компания, то это не вариант. Проблемы недостаточно богатой инфраструктуры здесь будут выходить на первый план; ты не сможешь гарантировать, что язык не загнётся, когда ключевых авторов собьёт автобус, и что будет компилятор этого языка под архитектуру процессора новой игровой приставки. Фактически, у тебя только два бескомпромиссных варианта: либо писать свой язык (если ты совсем ниндзя-самурай), либо перестать бояться и полюбить С++.

Пост бы был грустным, если бы не одно «но»: я очень верю в будущее С++. Jai и компания потому никогда и не вытеснят С++, что он не стоит на месте. Сейчас у этих языков куча плюсов по сравнению с плюсами (простите за каламбур), но уже в ближайших стандартах С++ должен обзавестись модулями, концептами и корутинами, благодаря чему уже начнёт ощущаться, чуть ли не как новый язык. Две основные фишки Jai — компайл-тайм выполнение кода и рефлексия — по всей логике будут следующим шагом, как развитие constexpr и некоторых перспективных предложений по статической рефлексии. Даже если на воплощение этого в жизнь уйдёт 10 лет, этого времени всё равно недостаточно, чтобы успеть вытеснить С++ с рынка. Ну а если заглядывать совсем в далёкое будущее (и немного помечтать), то метаклассы Герба Саттера вообще должны перевернуть программирование и убрать всех конкурентов в этой весовой категории.
Это, конечно, не значит, что другие геймдев-ориентированные языки не надо разрабатывать и использовать. Надо! Это всё большой обкаточный полигон для экспериментов, наиболее удачные концепции которого через много лет и после долгих обсуждений в комитете попадут и в самый совершенный язык программирования. Ну, или у меня просто стокгольмский синдром от долгого использования С++ и я бред несу последний. Всякое может быть.
Ameba
#лайт
Достала меня ситуация с кучей мессенджеров. Психанул и начал писать свой единый клиент. Называется Aggregate Message Bar, сокращённо Ameba.

Да, всяких приложений, объединяющих мессенджеры, как грязи. Я какое-то время использовал врапперы вэб-версий (Franz, Rambox), смотрел мультиклиенты (Pidgin), интеграции ботами (Sameroom), ещё какие-то сервисы и протоколы. Но это всё не то и не так. Как говорится, если хочешь сделать что-то без фатальных недостатков — сделай это сам.

Амёба разрабатывается прежде всего под Android, но будет также работать на десктопах (Windows, Linux, OS X). С айфонами гемороиться лишний раз мне не охота, но при очень большом желании можно будет запихать и туда, так как создаётся приложение на Qt.

Программа минимум — поддержать API Telegram и Slack. Если попрёт, то можно будет добавить Twitter, Discord. Может быть что-то ещё. Для начала ограничимся текстом с базовым форматированием, блоками кода, картинками, ссылками. Но сверху на это накрутим группировку каналов и подобные плюхи. Схему аккаунтов и группировку чатов планирую сохранять и синхронизировать через AWS AppSync. Опционально можно будет хранить там же и пароли.

Ориентир в плане юзабилити для меня — это телеграм. Но в Qt, к сожалению, нет стандартного контрола для редактирования текста, вменяемого работающего на мобилках; поэтому придётся все тачи и драги над текстом обрабатывать самому. На данный момент именно этим занят. Следить за разработкой и ставить звёзды можно на github (это open source):
https://github.com/Alprog/Ameba

И да, если вы находите текущий логотип уродливым, но готовы нарисовать и подарить мне более красивый — я весь внимание.
Ещё одна история о том, как попасть в профессию (как будто таких мало)
#лайт
Сегодня мне исполняется 29 лет со дня рождения и ровно 9 лет, как я официально работаю в индустрии. Это повод для меня вспомнить, как это было, и написать свою версию ответа на один из вечных вопросов новичков: как же разорвать замкнутый круг, когда для трудоустройства требуется опыт, а для получения опыта требуется трудоустройство?

Итак, осень 2008 года. Мне 19, я студент третьего курса, который только что закончил маленькую тактическую RPG на Visual Basic 6.0 (её скриншот вынесен в заголовок поста), которую пару лет делал по вечерам с командой, собранной в интернете. Проект так и назывался: «Маленькое и Скромное РПГ», так как создавался исключительно по фану и состоял почти полностью из говнокода. На этом мой опыт по большому счёту заканчивался. Контора, в которой я хотел работать, переехала в другой город, а в единственной оставшейся студии видеоигр требовались только флэшеры.

О существовании этой компании я узнал только потому, что туда взяли моего друга. Он устроился как раз флэшером и фактически закрыл собой все потребности студии. Но мы почему-то думали, что и мне место тоже найдётся: надо только подучить флэш. Он выдал мне графику от их матч-3 игры и я за недельку попутного изучения флэша собрал базовый прототипчик, с чем радостно прибежал на собеседование.

Там мне сказали, что это всё замечательно, но сейчас проектов нет (вакансия к этому моменту действительно уже пропала с сайта), но есть планы делать в будущем большой флэш проект (забегая вперёд скажу, что когда я оценил обстановку изнутри компании, стало понятно, что дальше разговоров этот проект и не мог пойти). Ещё сказали, что им нужен человек на фултайм, а я студент. И ещё что нет опыта, но если что, то мне позвонят. Я взял визитку и ушёл в дождь. В тот день было ясно, но для драматизма ситуации скажу, что ушёл в дождь.

В июне, как только сдал сессию, я написал им снова. Мол, летом я свободен на весь день. На этот раз мне не ответили. Я написал ещё раз и опять тишина. Тогда я достал визитку директора и тупо позвонил ему на личный мобильник. Мне сказали, что вообще не ищут сейчас новых сотрудников и тогда я предложил взять меня «на практику от универа», что означало поработать за чай и печеньки. И меня взяли. А через месяц, в мой двадцатый день рождения, предложили принять меня в штат. И я даже не сразу согласился на начальные условия, а поторговался.

Вот, собственно, и весь секрет. Даже если нет нигде вакансий, требуется немного напористости и готовность 1-2 месяца поработать за очень мало или за печеньки — и вот у вас уже есть опыт. Замкнутый круг разорван, вы теперь востребованный джун, и с вами уже совсем по-другому разговаривают. А дальше — больше.
Мудрость про таск-трекеры
#лайт
Знаете, что самое важное в трекере задач? Инструменты отчётности? Уведомления? Может быть, интеграция с системой контроля версий? Не, это всё фигня. Самое важное — это количество кликов при работе с ним.

Вы можете что угодно думать по поводу того, что пара лишних кликов ничего не меняют; но когда вам нужно указать тип задачи, компонент, теги и сроки, чтобы тупо создать задачу, вы просто не будете этого делать. Создать задачу должно быть также легко, как записать её в блокнот. Также быстро, как сказать её соседу. Если для создания задачи «выровнять логотип по центру экрана» требуется сильно больше действий, чем просто ввести этот текст, то вы обязательно рано или поздно поленитесь это сделать. Или напишите это в чат напрямую ответственному, воруя время у себя, у него, и ещё рискуя потерять эту задачу в будущем.

Это может показаться мелочью, но только до тех пор, пока один раз не ощутите разницу. Я помню, как на одном проекте мы за день вдвоём закрыли более ста тасок. Мелких тасок в духе передвинь что-то на три пикселя вправо или поменяй иконку. Мелких тасок, про которые бы все забыли и которые иначе портили бы впечатление от игры. Но нам было не лень их записывать по ходу и они не потерялись.

У нас тогда был собственный багтрекер, до сих пор недостижимый идеал в плане количества кликов при работе с ним. Я не рекомендую вам писать своё, но советую повозиться с настройками вашего трекера. Тратя время на то, чтобы сократить один клик, вы в конечном итоге экономите человеконедели.
Мам, на меня смотрят тёлки
#лайт
Выступал вчера с докладом на местом геймдев-митапе. Рассказывал, каково это быть техдиром на удалёнке. Записей никаких нет, но есть мнение, что я топ-докладчик. У меня это уже третий опыт подобных выступлений и с каждым разом заходит лучше и лучше. Я изначально довольно скептически отношусь к полезности 99% докладов на конференциях (включая свои), поэтому упор делаю на подачу: пусть людям будет хотя бы интересно это слушать. Нет, толика смысловой нагрузки, конечно, в моих докладах имеется, но я всё приправляю шуточками и смешными слайдами. Шутки при этом стараюсь встраивать нативно в рассказ, а слайдами играю в основном на неожиданности. И ещё громкими тезисами кидаюсь, чтобы не засыпал народ. Думаю, у меня хорошо получается чувствовать аудиторию. Правда, речь хромает: всё ещё много экаю.

Ну а ещё по фоткам я наконец-то увидел, как растолстела моя ряха за последние полгода. Надо завязывать с доставками еды и налягать на баскетбол.
Девлог #0
#лайт
Начали снимать дневники разработки по Encased. В этом выпуске общая информация про игру, а также рассказываем о работе с комьюнити. Ребята на видео как-то подозрительно много улыбаются. Наверное, потому что меня пока нет в офисе. Ну, ничего — в августе навещу их снова!

https://www.youtube.com/watch?v=z5lMainBskQ
Сумбурная объяснялка про тайлики и рамочки
#код
Обещался побольше рассказывать про код Encased, а не пишу совсем. Нехорошо. Будем исправляться. Сегодня незначительная, но довольно замороченная тема: как рисуется у нас рамка для зон досягаемости под ногами персонажа.

Начать придётся с конца. Ходят персонажи у нас не по 2D-пространству, а по сложному 3D ландшафту со всякими ямочками, холмиками, мостиками через канаву и вторыми этажами. А потому игровая сетка — штука сложная: не массив, а самый настоящий граф. В большинстве случаев одна игровая клеточка это ровно один квад, но иногда, на всяких неровных поверхностях, это 16 квадиков помельче (4x4). Так или иначе, вертексы этих квадиков имеют две текстурные координаты. Одна хранит локальные координаты внутри клетки, другая же — индекс клетки. Ну просто порядковый номер клетки (интовый), так как граф может иметь самую разнообразную форму и 2D-координаты на него не натянешь.

Ещё есть специальная текстура, которая динамически меняется во время игры и где каждый тексель (по порядковому номеру) указывает шейдеру на то, какой спрайт нужно выводить в этой клетке. У текселя 4 компоненты RGBA, которые прекрасно кодируют Rect спрайта внутри атласа. Более того, как несложно заметить, переставив каналы местами, мы бесплатно получаем ещё и любые зеркальные отражения спрайтов.

Осталось эти спрайты нагенерить. Но не рисовать же все варианты спрайта, правда же? Поэтому делим спрайт на 4 части и рисуем варианты только для левого-верхнего уголочка. У меня получилось 5 видов: пустой, горизонтальная грань, вертикальная грань, обе грани, уголочек (см. рисунок). Это кодируется тремя битами. Кусочков 4, так что полностью спрайт определяется 12-битным числом. Если оставить только возможные комбинации, то их 625 (5^4). Пробегаемся по этим вариантам, проверяем их на валидность (биты горизонтальной и вертикальной линии у соседних кусочков должны совпадать) и генерим спрайты. Попутно, разумеется, чекаем их на зеркальность и составляем мапу (12-битное число -> 12-битное число + вид зеркального отображения). И получается всего навсего 20 уникальных спрайтов.

Далее зашиваем это всё в атлас вместе со всякими другими спрайтами для других режимов отображения (само собой, своей собственной зашивалкой). Ну и потом в игре вычисляем зону досягаемости, смотрим на соседей каждой клетки и составляем для неё 12-битный индекс, лезем в мапу, достаём оттуда другой индекс и режим отображения, из данных атласа получаем соответствующий рект, пишем это дело в нужный тексель текстуры, а в шейдере читаем и рисуем на нужном месте. Готово.

Если вы уследили за моей мыслью, держите пятюню. Если в какой-то момент поплыли — буду рад фидбеку, где именно я пишу непонятно. А если я у вас отбил всякое желание стать графическим программистом, то я не специально.
Феерическая расстановка точек над Unity
#лайт
На прошлых выходных занесло меня на re:indiehive в Минске. Это такое сборище инди-разработчиков на веранде бара, где каждый может подойти к микрофону и показать на большом экране свой замечательный шедевр. В конце организаторы устроили круглый стол «Что выбрать: Unreal, Unity или Defold?»; и кто знаком со мной лично, тот уже знает, с какими примерно речами я туда влез. А вот большинство читателей моего канала об этом ещё не слышали, а потому я надумал наконец внятно сформулировать свою теорию в виде поста.

Если коротко: Unity — зло, нанесшее непоправимый урон индустрии и уничтожившее целое поколение программистов. Если же мысль разворачивать, то мой хейт этого движка имеет две основных составляющих: техническую и идеологическую. О технических проблемах сказано уже немало слов, да и с появлением таких вещей, как ECS и ScriptableRenderPipeline, ситуация последнее время стала улучшаться. Поэтому я остановлюсь на второй и основной претензии — идеологической.

Зададимся вопросом: почему бизнес выбирает Unity? Не потому что на нём удобно разрабатывать, не потому, что он имеет какие-то технические преимущества; бизнес выбирает Unity в первую очередь из-за того, что у него огромное количество успешных шоукейсов, а на рынке полно специалистов: их легко найти и в случае чего безболезненно заменить. С точки зрения ведения бизнеса, это идеально. Да и разработчикам, в принципе, неплохо: достаточно изучить один простой движок и ты уже востребованный специалист. Больше разработчиков Unity — больше вакансий. Больше вакансий — больше разработчиков. Ком растёт и в какой-то момент превращается в чёрную дыру, из которой уже ничего не возвращается.

В один период своей карьеры, ваш покорный слуга, некогда разносторонний программист, тоже чуть было не был поглощён этой дырой. Я перестал развиваться и вращался только на орбите Unity, медленно приближаясь к горизонту событий. Вырваться мне помогло лишь моё движкописательство. Я смог найти проекты на С++ и спасся. Но большинство тех, кто помоложе, оказалось менее удачливо и превратилось в Unity-программистов.

— А что, собственно, плохого в том, чтобы знать только Unity? — спросите вы.

Просто посмотрите, какие требования к программистам были в индустрии 10 лет назад. Достаточно пробежаться глазами по вопросам знаменитой статьи Бориса Баткина «интервью глазами пострадавшего» и убедиться, что мы бы не ответили и на половину. И сравнить это с сегодняшним днём, когда на собеседования приходят так называемые Unity-программисты с опытом разработки 3D игр более двух лет и неспособные ответить на вопрос «Что такое Depth Buffer?»

И ведь нельзя сказать, что люди стали тупее. Им просто негде стало расти. Кругом только мобильные проекты на Unity. И соответствующего уровня разработчики. Открой сейчас крутейший офис в Москве и дай денег на разработку Uncharted 5, нанять будет некого. У нас не наберётся столько спецов такого уровня. И дальше будет только хуже, петля затягивается.

Вомгла 2008 года это болезнь индустрии, а Unity — антибиотик. Но если все начнут применять антибиотики по пустякам, их действие ослабевает и появляются суперштаммы, устойчивые даже к самым сильным антибиотикам. Выбирая Unity, вы упрощаете жизнь себе сейчас, но усугубляете ситуацию в индустрии в целом в будущем.

Хотел бы я сказать, что мы в Dark Crystal Games поступаем более ответственно, но, увы, наша первая игра тоже на Unity; и не факт, что мы сможем соскочить с этой иглы. Особенно, если следующий проект будет похож на нынешний.

Верю ли я в то, что ситуация в российском геймдеве когда-нибудь изменится? Да. Знаю ли я, как это сделать? Нет.
Счастливый отзыв о серебряной пуле в мире VCS
#лайт
Не пытайтесь вспомнить другую расшифровку аббревиатуры VCS, речь в этой заметке действительно пойдёт о системах контроля версий. Казалось бы, ну сколько можно уже? Вроде бы программисты всего мира давно уже определились и решили, что для распределённой разработки ничего лучше git’а не существует. Есть, правда, горстка староверов, которые по собственной воле продолжают истязать себя SVN, но, надеюсь, среди моих читателей таких немного (фу такими быть). В наше время всё же большинство пилит софт в git’е и горя не знает. Везде, кроме геймдева. Потому что у нас, помимо непосредственно девелоперов, есть ещё артисты. И с ними вечно какие-то проблемы. Как говорится, курица не птица, артист — не разработчик.

Проблемы с художниками две. Во-первых, их тонкая душевная организация плохо сочетается с философией git’а. Будем честны, не каждый программист в неё вникает сразу, чего уж ждать от людей творческих. Справляются с этой проблемой в разных студиях по-разному: кто-то заводит для артистов отдельный SVN репозиторий; кто-то вставляет за ними графику руками; есть даже те, кто утверждает, что ценой невероятных усилий умудряется обучать гиту своих художников (до конца не верю!); кому-то боль облегчает git-flow; но в той или иной степени, страдают все.

Вторая проблема с артистами заключается в том, что они имеют обыкновение коммитить бинарный арт килотоннами, и на том же bitbucket’е место заканчивается мгновенно, а решения типа LFS помогают слабо, т.к. требуют соединения с сервером и убивают этим всю суть распределённой системы (по ревизиям уже просто так не попрыгаешь локально).

И вот обе эти проблемы, как по волшебству, решает PlasticSCM. Это VCS, созданная специально для нужд геймдева. У неё есть два режима работы. Первый как в git: у вас есть рабочая копия репозитория со всей историей, вы можете локально делать ветки, мержи, стэши и всё остальное, к чему привыкли. И второй режим для артистов: всё то же самое, но репозиторий храниться не у вас, а в облаке. То есть у вас commit всегда сопряжён вместе с push, а update с pull’ом. Это уже само по себе отсекает половину ситуаций, вызывающих сложности. Но плюс к этому, в пластике ветки являются не легковесными метками, а полноценными объектами. Каждый changeset (ревизия по здешнему) жёстко привязан к какой-то конкретной ветке. Другими словами, объекты, которыми оперирует пользователь, точно отражают термины, в которых он думает (по крайней мере, если вы работаете по схеме git-flow). В такой системе гораздо ниже вероятность совершить ошибку. Здесь в принципе не может возникнуть ситуации, вроде оторванной головы, которую сложно решить, не понимая низкий уровень. И как показывает практика, контевики тут вполне осваиваются и справляются даже с ветками.

Есть ещё в пластике третий режим. Это отдельный клиент, где нет веток вообще, а пользователь всегда сидит на последней ревизии main’а. Но этот режим совсем для слабаков и мы его не используем. Также есть ещё lock-и файлов, как в Perforce, но Unity плевать хотело на readonly флаги, поэтому ими мы тоже не пользуемся.

Что касается проблемы с большими файлами, то примерно за те же деньги, что на Bitbucket дают 100 GiB LFS, в PlasticSCM дают 100 GiB основного репозитория. Да, рабочие копии у программистов пухнут, но это меньшее из зол. Обрезать историю, к сожалению, возможности нет, но можно выкачивать отдельные ветки. То есть, если будет совсем невмоготу, в качестве костыля всегда можно сделать бранч от начала проекта и залить туда текущий слепок проекта.

Мы работаем с пластиком уже 5 месяцев и очень довольны. Но для своих личных проектов, я, понятное дело, всё равно буду использовать git. Впрочем, ещё до того, как я узнал о существовании PlasticSCM, я начинал делать клиент для git, реализующий похожие идеи в интерфейсе по упрощению работы с ветками. Называться он должен был GitTern. Может быть, ещё вернусь к нему, когда загруз по работе пройдёт. Но это уже совсем другая история.
Развлекалочка для программистов
#кодище
Последняя запись на канале заканчивалась тем, что у нас загруз на работе; поэтому я и пропадал так долго. Но вот мы наконец-то залили в последнюю минуту билд, его сейчас показывают всяким разным игрожурам в Сан-Франциско, а я могу вздохнуть свободно и оглядеться по сторонам. Писать обстоятельный пост про какую-нибудь нашу подсистему у меня сейчас нет никаких сил, поэтому развлеку вас пока небольшой приколюхой для программистов.

Думаю, после нормальной сишечки каждого ужасно бесит, что в шарпе нельзя ссылочные типы проверять на null простым условием:
if (refObject)

а приходится писать
if (refObject != null)


Классическое решение — неявный оператор каста в bool. Я вот почти все свои классики наследую от Boolable:
public class Boolable 
{
public static implicit operator bool(Boolable ref)
{
return ref != null;
}
}


Догадываетесь, что может пойти не так? А кейс на самом деле достаточно интересный. Вот есть у вас два класса, наследуемых от Boolable: A и B, и вам надо в каком-то месте проверить равенство объектов:
if (foo1.objectA == foo2.objectA)

но вы маленько опечатались и сравнили объекты разных типов:
if (foo1.objectA == foo2.objectB)


Не смотря на то, что мы передаём разные объекты, условие будет всегда срабатывать, если объекты Boolable. Счастливой отладки, как говорится :)