tox1cozZ

aka Agravaine
8,454
598
2,890
Бывает, сталкиваешься с проблемами и никак не удается их решить. Либо вообще нет решения в интернете, либо у всех работает, а у тебя почему-то нет.
Расскажу про несколько фич(костылей, ага), которые помогли мне решить проблемы и сделать коддинг чуточку приятнее.

1. IDEA не грузит ресурсы(текстуры, модели и т.д)
Да, в инете есть панацея в виде такой строчки в build.gradle:
idea.module.inheritOutputDirs = true
И оно отлично решает проблему. Но, как оказалось, не всегда и не у всех. Помнится, кто-то на форуме даже страдает на постоянной основе из-за этого.
У меня три проекта и во всех ресурсы работают. Но вот понадобилось создать еще один проект, настроил абсолютно идентично, и появилась беда... Вообще ни в какую не пашет. Собирать мод и тестировать на стороннем лаунчере - слишком долго и геморно.
Правильное решение (спасибо @Ivasik):
После обновления от 19 года, идея стала использовать сборку граблей, а именно "раскидывание" ресурсов и классов по разным папкам. Ранее данная "фича" не была введена и всё забрасывалось идеей в одну папку. Чтобы исправить это, надо лишь изменить сборку и запуск с Gradle на IDEA:
1580573042182.png
Ну и всё, далее ресурсы мода будут грузиться как и раньше.

2. Проблема с установкой рабочего пространства 1.7.10 и 1.12.2
Фордж славится тем, что на старых версиях постоянно что-то ломают. Сейчас вообще нельзя развернуть среду без плясок с бубном.
Настоятельно рекомендую использовать данный форк. Мало того что всё работает из коробки, так еще и завезли поддержку миксинов и прочих вкусностей (спасибо @Aizistral).

3. Проблемы с HotSwap
Когда запускаешь только клиент - все замечательно, никаких проблем нет. Но как только запускаешь еще и сервер - всё, хотсвап сразу ломается, идея говорит мол "ты удалил/добавил методы, сорян, я не умею так". Как такое может быть, если я просто изменил значение локальной переменной в методе?
Всё дело в фордже и его трансформере, который вырезает всё что помечено SideOnly. Методы/переменные вырезаются и идея думает что это мы ручками что-то убрали в классах.
Да, можно юзать JRebel или DCEVM. Насчёт первого не знаю, но вот второй дико лагучий. Если с одним клиентом еще терпимо, то когда открываешь два во время хотсвапа дико начинает тормозить секунд 15, проц забивается на 100%, а у меня на минуточку не самый хреновый i5.
Решение простое:
Открываем класс SideTransformer и копируем себе в проект в такой же пакет который и был. На 1.7.10 так, на 1.12 вроде немного другой.
1576239743111.png
Открываем его и заменяем код на заглушку.
1576239771764.png
Вот и всё. Идея сама подгружает эти классы и заменяет ими стандартные, поэтому все будет работать и SideOnly ничего вырезать не будет. Только не нужно включать этот класс в собранный мод, хорошо?
Как и ожидалось, хотсвап отлично пашет.

4. Подмена стандартных классов
В предыдущем пункте как раз это и делаем. То есть ты можешь полностью скопировать класс из майна/форджа/другого мода к себе в какой же пакет и идея будет подтаскивать именно его.
Зачем это нужно?
Например, чтобы сделать фикс в стороннем моде, а декомпилить(а в последствии править кучу ошибок во всём моде) или тащить весь мод ради изменения одного класса... Ну такое. А тут взял нужный класс и все, а мод подключил как либу.
Либо же пришла идея, ради которой нужно изменить ванильный класс. Городить сразу же хуки или трансформеры ради сомнительной фичи - слишком долго и муторно. А так взял класс, отредактировал как нужно и потестил. Получилось - сделал это хуками, не получилось - удалил класс и всё.
Кстати, можно с помощью BON'a поменять маппинги скомпилированного класса и запихнуть в minecraft.jar, удалив META-INF и не использовать никакие трансформеры (спасибо @Javanoob).

5. Изменение ассетов без перезагрузки игры
Можно ассеты(текстурки, например) перезагружать\докидывать без перезапуска игры.
Собсна, сначала меняешь\добавляешь ассетики в папку с ресурсами, затем в верхнем списке Run тыкаешь Reload changed classes и в игре жмёшь F3+T (спасибо @Plasticable).

6. Проблемы с Gradle в новых версиях IDEA
По-умолчанию в 1.7.10 версии стоит версия Gradle 2.0, но новая IDEA не работает с такой древней версией граблей.
Идём в папку проект/gradle/wrapper и открываем gradle-wrapper.properties. Меняем строку на distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-all.zip, тем самым обновляем версию до 4.4.1 и всё будет работать.

P.S Если ты знаешь похожие фичи - пиши, будем дополнять статью.
 
Последнее редактирование:

Sainthozier

Стрелочник
623
11
369
Третий пункт заинтриговал, не знал о таком раньше. Идея мне ясна, но можно какой-нибудь практический пример на коленке, пожалуйста? )
 
145
7
31
Просто создаёшь пакет и класс такой же, как в исходниках майна и всё. Кстати, можно с помощью BON'a поменять маппинги скомпилированного класса и запихнуть в minecraft.jar и не использовать никакие трансформеры, но вроде это нарушает eula.
 

tox1cozZ

aka Agravaine
8,454
598
2,890
можно какой-нибудь практический пример
Во втором пункте как раз практический пример. Да, это все что нужно сделать ;)

можно с помощью BON'a поменять маппинги скомпилированного заменённого класса и запихнуть в minecraft.jar
Ох, бон умеет менять названия класса и файла? Круть, а то градл не меняет)
 
7,099
324
1,509
Если ты знаешь похожие фичи - пиши, будем дополнять статью
Идея не грузит ресурсы
Помимо ресурспака есть еще один действенный метод: самому закинуть ресурсы в ./classes/production/<module>. Ресурсы обновляются редко(у меня), поэтому это довольно удобно. Еще можно сделать символическую ссылку вместо копирования

весь мод ради изменения одного класса
Стоит отметить, что если не все классы в одном jar были скомпилены одной версией компилятора, то могут возникать NoClassDefFoundError(а может не из-за версии компиля, я не исследовал этот вопрос глубоко), так что частичная перекомпиляция это скорее антипаттерн
 
Последнее редактирование:

tox1cozZ

aka Agravaine
8,454
598
2,890
./classes/production/<module>
Хз, они и так там лежат, но все равно не видит.

Стоит отметить, что если не все классы в одном jar были скомпилены одной версией компилятора, то могут возникать NoClassDefFoundError
Сколько уже занимаюсь подобным и ниразу таких проблем не наблюдал..
 
7,099
324
1,509
Не наблюдал потому что, вероятно, делаешь правки в один только майн и пару модов, вероятность нарваться низкая и тебе повезло. А вот мне приходилось вносить правки во множество модов в сборках всяких хайтеков и магиков, где jar-ок разных авторов больше, следовательно, вероятность больше
 
7,099
324
1,509
Упс, забыл что это профичи idea. В среде как раз удобнее черновик делать именно так
 

Sainthozier

Стрелочник
623
11
369
У меня idea время от времени индексирует заново все файлы. Зачем и почему она это делает, знает кто? Немного бесит, т.к. она стоит на hdd и индексирование всех файлов, особенно если очень много легковесных, иногда сопровождается микрофризами :с
 

Icosider

Kotliner
Администратор
3,600
99
663
Не наблюдал потому что, вероятно, делаешь правки в один только майн и пару модов, вероятность нарваться низкая и тебе повезло. А вот мне приходилось вносить правки во множество модов в сборках всяких хайтеков и магиков, где jar-ок разных авторов больше, следовательно, вероятность больше
105 модулей с модами в одном проекте, которые также имею подмодули client/server, всё собирается без проблем.

@Agravaine :j, с текстурпаками идея конечно хорошая, сам пользовался до этой статьи, но это не всегда удобно. Кстати, интеллидж создаёт доп модули api, main, test, не знаешь как такое решить? Это началось после обновления 2019.1, ранее не наблюдал:unsure:
 

Icosider

Kotliner
Администратор
3,600
99
663
Прикол в том, что удалением папки так просто не отделаться, а всяких .iml, .imr файлов создаётся тонна
 

Icosider

Kotliner
Администратор
3,600
99
663
Тоже самое, но файлы всё равно генерируются
Аннотация 2019-12-21 124825.png
 
7,099
324
1,509
105 модулей с модами в одном проекте, которые также имею подмодули client/server, всё собирается без проблем
Допустим. А что тогда было источником моих проблем с NoClassDefFound?
 

Icosider

Kotliner
Администратор
3,600
99
663
Не знаю. У меня так:
Gradle (Groovy):
duplicatesStrategy = DuplicatesStrategy.EXCLUDE

if (project.mergeWithDep)
   from(zipTree("$libModDir/${project.name}-${project.version}.jar"))
А сами зависимости подхватываются автоматически, как и преобразуются из *.jar в dev.jar и dev-sources.jar. Для подобных манипуляций использовал: свою модификацию BON + fernflower + cfr и соответственно всё в плагин для gradle запаковал, проблем не наблюдаю
 
292
14
160
Если ты знаешь похожие фичи - пиши, будем дополнять статью.
Ну я знаю одну полезную. Можно ассеты(текстурки, например) перезагружать\докидывать без перезапуска игры.
Собсна, сначала меняешь\добавляешь ассетики в папку с ресурсами, затем в верхнем списке Run тыкаешь Reload changed classes и в игре жмёшь F3+T

во время хотсвапа дико начинает тормозить секунд 15, проц забивается на 100%
Я думал, это из-за моего фигового компа, а это у всех так...
 

Sainthozier

Стрелочник
623
11
369
Но, как оказалось, не всегда и не у всех.
Да оно живое, походу. То работает, то нет, хз вообще от чего зависит. Условия и воркспейс идентичные, а результат разный.
Короче всё же не долго я смог просидеть на эклипсе, чувствую себя инвалидом на нём, перешёл обратно на идею, вписал в build.gradle такую строчку: sourceSets { main { output.resourcesDir = output.classesDir }} и всё заработало, все текстуры и ассеты грузятся без проблем, не придётся танцевать с бубном и ресурспаком )
Так что мне кажется, что панацея это sourceSets { main { output.resourcesDir = output.classesDir }}, а не idea.module.inheritOutputDirs = true.

Но есть один неприятный прекол - я не могу в ide создавать директории для ассетов, тупая идея всё равно склеивает папки, а потом майн опять не видит ассеты, даже если я пропишу и первую, и вторую строчки. Так что приходится ручками через проводник создавать, печально. Idea 2019.3.1 если что :с
 
Сверху