Skip to content

Commit

Permalink
Port to Template Dev Env
Browse files Browse the repository at this point in the history
(template is latest from this commit on main [c19ab24](CleanroomMC/TemplateDevEnv@c19ab24))

Important:

- Migrated mcmod.info and other related options to "gradle.properties", these should be the same unless stated.
- Migrated dependencies to "dependencies.gradle" (under "../gradle/scripts/")
- "Fixed" not being able to run the dev client ("runClient" gradle task), there is a big note on "dependencies.gradle" as to how I partially "fixed" (hence the quotes) it.
- Renamed "vintagium.mixin.json" to "mixin.vintagium.json" (and propagate changes to SodiumMixinTweaker::getMixinConfigs) to fit style enforced by gradle.build by default

Other minor changes:

- Removed support for version 1.13 as the template is too embedded into Cleanroom (1.12.2 only so far)
- Upgraded Gradle to 8.12
- Upgraded foojay-resolver-convention to 0.8.0
- Upgrade to minimum Mixin version of 0.8.5
- In "mixin.vintagium.json" file I added the follow entry->
"target": "@env(DEFAULT)"
This might not be wanted but the template had it so I might as well add it (no idea what it does)
  • Loading branch information
Levviata committed Feb 2, 2025
1 parent 01a3aef commit bdb5d0c
Show file tree
Hide file tree
Showing 15 changed files with 844 additions and 174 deletions.
392 changes: 329 additions & 63 deletions build.gradle

Large diffs are not rendered by default.

144 changes: 125 additions & 19 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,20 +1,126 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
# Gradle Properties
org.gradle.jvmargs = -Xmx3G
#-DsocksProxyHost=127.0.0.1 -DsocksProxyPort=1081
#org.gradle.java.home=C:/Program Files/Java/jdk-1.8

minecraft_version=1.12.2
minecraft_version_range=[1.12,1.13)
forge_version=14.23.5.2860
forge_version_range=[23,)
loader_version_range=[23,)
mappings_channel=stable
mappings_version=39-1.12

mod_id=vintagium
mod_name=Vintagium
mod_main_class=SodiumClientMod
mod_version=0.1
mod_base_package=me.jellysquid.mods.sodium
mod_description=Vintagium is a fork of Sodium, which is a free and open-source \noptimization mod for Minecraft which improves frame rates and reduces lag spikes.

# Source Options
# Use Modern Java(9+) Syntax (Courtesy of Jabel)
use_modern_java_syntax = false

# Compilation Options
generate_sources_jar = true
generate_javadocs_jar = false

# Testing
enable_junit_testing = true
show_testing_output = false

# Mod Information
# HIGHLY RECOMMEND complying with SemVer for mod_version: https://semver.org/
mod_version = 0.1
root_package = me.jellysquid.mods.sodium
mod_id = vintagium
mod_name = Vintagium

# Mod Metadata (Optional)
mod_description = Vintagium is a fork of Sodium, which is a free and open-source \noptimization mod for Minecraft which improves frame rates and reduces lag spikes.
mod_url =
mod_update_json =
# Delimit authors with commas
mod_authors = Nano, Liveembeddedt, CaffeineMC
mod_credits =
mod_logo_path = assets/sodium/logo.png

# Mapping Properties
mapping_channel = stable
mapping_version = 39
use_dependency_at_files = true

# Run Configurations
# If multiple arguments/tweak classes are stated, use spaces as the delimiter
minecraft_username = Developer
extra_jvm_args =
extra_tweak_classes =

# Maven Publishing (Provide secret: MAVEN_USER, MAVEN_PASS)
publish_to_maven = false
# Good for debugging artifacts before uploading to remote maven
# GitHub actions won't run if this is true, test this by running the task `publishToMavenLocal`
publish_to_local_maven = false
maven_name = ${mod_name}
maven_url =

# Publishing
# release_type can only be: release, beta or alpha (applies to CurseForge / Modrinth)
release_type = release
publish_with_changelog = ${{ it.file('CHANGELOG.md').exists() }}

# Publishing to CurseForge (Provide secret: CURSEFORGE_TOKEN)
# To configure dependencies, head to publishing.gradle's curseforge block
publish_to_curseforge = false
# CurseForge project ID must be the numerical ID and not the slug
curseforge_project_id =
curseforge_debug = false

# Publishing to Modrinth (Provide secret: MODRINTH_TOKEN), the token must have the `CREATE_VERSION` and `PROJECT_WRITE` permissions
# To configure dependencies, head to publishing.gradle's modrinth block
publish_to_modrinth = false
modrinth_project_id =
# Allows gradle to publish updated READMEs to the project body (via the modrinthSyncBody task)
modrinth_sync_readme = false
modrinth_debug = false

# If any properties changes below this line, refresh gradle again to ensure everything is working correctly.

# Modify Minecraft Sources
# RetroFuturaGradle allows Minecraft sources to be edited, and have the changes reflected upon running it
# Good for previews when coremodding, or generally seeing how behaviours can change with certain code applied/unapplied
# Turning this on allows Minecraft sources to persist and not regenerate
change_minecraft_sources = false

# Tags
# A RetroFuturaGradle concept akin to Ant ReplaceTokens
# A class is generated at build-time for compilation, to describe properties that have values that could change at build time such as versioning
# Class name is configurable with the `tag_class_name` property
# Tag properties can be stated in the `tags.properties` file, references are allowed
use_tags = true
tag_class_name = ${root_package}.${mod_id}.Tags

# Access Transformers
# A way to change visibility of Minecraft's classes, methods and fields
# An example access transformer file is given in the path: `src/main/resources/example_at.cfg`
# AT files should be in the root of src/main/resources with the filename formatted as: `mod_id_at.cfg`
# Use the property `access_transformer_locations` to state custom AT files if you aren't using the default `mod_id_at.cfg` location
# If multiple locations are stated, use spaces as the delimiter
use_access_transformer = true
access_transformer_locations = META-INF/${mod_id}_at.cfg

# Mixins
# Powerful tool to do runtime description changes of classes
# Wiki: https://github.com/SpongePowered/Mixin/wiki + https://github.com/CleanroomMC/MixinBooter/ + https://cleanroommc.com/wiki/forge-mod-development/mixin/preface
# Only use mixins once you understand the underlying structure
use_mixins = true
mixin_booter_version = 10.2
# A configuration defines a mixin set, and you may have as many mixin sets as you require for your application.
# Each config can only have one and only one package root.
# Generate missing configs, obtain from mixin_configs and generate file base on name convention: "mixins.config_name.json"
# You should change package root once they are generated
generate_mixins_json = true
# Delimit configs with spaces. Should only put configs name instead of full file name
mixin_configs = ${mod_id}
# A refmap is a json that denotes mapping conversions, this json is generated automatically, with the name `mixins.mod_id.refmap.json`
# Use the property `mixin_refmap` if you want it to use a different name, only one name is accepted
mixin_refmap = mixins.${mod_id}.refmap.json

# Coremods
# The most powerful way to change java classes at runtime, it is however very primitive with little documentation.
# Only make a coremod if you are absolutely sure of what you are doing
# Change the property `coremod_includes_mod` to false if your coremod doesn't have a @Mod annotation
# You MUST state a class name for `coremod_plugin_class_name` if you are making a coremod, the class should implement `IFMLLoadingPlugin`
is_coremod = true
coremod_includes_mod = true
coremod_plugin_class_name = me.jellysquid.mods.sodium.client.SodiumMixinTweaker

# AssetMover
# Convenient way to allow downloading of assets from official vanilla Minecraft servers, CurseForge, or any direct links
# Documentation: https://github.com/CleanroomMC/AssetMover
use_asset_mover = false
asset_mover_version = 2.5
91 changes: 91 additions & 0 deletions gradle/scripts/dependencies.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
apply from: 'gradle/scripts/helpers.gradle'

repositories {
// Other repositories described by default:
// CleanroomMC: https://maven.cleanroommc.com
exclusiveContent {
forRepository {
maven {
name 'CurseMaven'
url 'https://cursemaven.com'
}
}
filter {
includeGroup 'curse.maven'
}
}
exclusiveContent {
forRepository {
maven {
name 'Modrinth'
url 'https://api.modrinth.com/maven'
}
}
filter {
includeGroup 'maven.modrinth'
}
}
mavenLocal() // Must be last for caching to work
}

dependencies {
// Include StripLatestForgeRequirements by default for the dev env, saves everyone a hassle
runtimeOnly 'com.cleanroommc:strip-latest-forge-requirements:1.0'
// Include OSXNarratorBlocker by default for the dev env, for M1+ Macs
runtimeOnly 'com.cleanroommc:osxnarratorblocker:1.0'

/*
These only compile on build and not runtime, the client doesn't check for these dependencies in theory.
In the ideal world we would need to check if these mods/dependencies exist in the runtime environment and promptly load them--
which isn't something I know how to implement sadly, though I elaborate more about this below.
*/
compileOnly rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848")
compileOnly rfg.deobf("curse.maven:censoredasm-460609:4800875")
compileOnly rfg.deobf("curse.maven:fermiumasm-971247:5116326")

/*
Old code was this:
dependencies {
[...]
// mod compat
implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848")
implementation rfg.deobf("curse.maven:censoredasm-460609:4800875")
implementation rfg.deobf("curse.maven:fermiumasm-971247:5116326")
[...]
}
A more in-depth explanation;
When building normally (running the "build" gradle task) and then running the game externally (through your average launcher) this is fine,
but when trying to run "runClient" (run client gradle task) on the dev environment (a.k.a: dev env) it gracefully exits,
I pinpointed this to the client (in our dev env) hard depending on the mods when using "implementation" to add them to the "dependencies" block.
To fix this you should check if in our "runClient" task (inside "../build.gradle") we have the required dependencies
(e.g: if statements to check run/mods?),
if present load the deps (we would use "runtimeOnly"*), else don't load them!
For the build task I suppose you would also want to do the same,
so if present load the deps (we would use "compileOnly"*), else don't load them!
* I don't know if that would be the proper way to add it, I'm simply theorizing :p
Pseudo code:
runClient {
if (haveDependencies)
{
runtimeOnly (...) // you may also want to deobfuscate (deobf) using retrofuturagradle (rtg), but no idea how that works.
}
}
build {
if (haveDependencies)
{
compileOnly (...) // you may also want to deobf using rtg, but no idea how that works again.
}
}
*/
}
5 changes: 5 additions & 0 deletions gradle/scripts/extra.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// You may write any gradle buildscript component in this file
// This file is automatically applied after build.gradle + dependencies.gradle is ran

// If you wish to use the default helper methods, uncomment the line below
// apply from: 'gradle/scripts/helpers.gradle'
96 changes: 96 additions & 0 deletions gradle/scripts/helpers.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import groovy.text.SimpleTemplateEngine
import org.codehaus.groovy.runtime.MethodClosure

ext.propertyString = this.&propertyString as MethodClosure
ext.propertyBool = this.&propertyBool as MethodClosure
ext.propertyStringList = this.&propertyStringList as MethodClosure
ext.interpolate = this.&interpolate as MethodClosure
ext.assertProperty = this.&assertProperty as MethodClosure
ext.assertSubProperties = this.&assertSubProperties as MethodClosure
ext.setDefaultProperty = this.&setDefaultProperty as MethodClosure
ext.assertEnvironmentVariable = this.&assertEnvironmentVariable as MethodClosure

String propertyString(String key) {
return $property(key).toString()
}

boolean propertyBool(String key) {
return propertyString(key).toBoolean()
}

Collection<String> propertyStringList(String key) {
return propertyStringList(key, ' ')
}

Collection<String> propertyStringList(String key, String delimit) {
return propertyString(key).split(delimit).findAll { !it.isEmpty() }
}

private Object $property(String key) {
def value = project.findProperty(key)
if (value instanceof String) {
return interpolate(value)
}
return value
}

String interpolate(String value) {
if (value.startsWith('${{') && value.endsWith('}}')) {
value = value.substring(3, value.length() - 2)
Binding newBinding = new Binding(this.binding.getVariables())
newBinding.setProperty('it', this)
return new GroovyShell(this.getClass().getClassLoader(), newBinding).evaluate(value)
}
if (value.contains('${')) {
return new SimpleTemplateEngine().createTemplate(value).make(project.properties).toString()
}
return value
}

void assertProperty(String propertyName) {
def property = property(propertyName)
if (property == null) {
throw new GradleException("Property ${propertyName} is not defined!")
}
if (property.isEmpty()) {
throw new GradleException("Property ${propertyName} is empty!")
}
}

void assertSubProperties(String propertyName, String... subPropertyNames) {
assertProperty(propertyName)
if (propertyBool(propertyName)) {
for (String subPropertyName : subPropertyNames) {
assertProperty(subPropertyName)
}
}
}

void setDefaultProperty(String propertyName, boolean warn, defaultValue) {
def property = property(propertyName)
def exists = true
if (property == null) {
exists = false
if (warn) {
project.logger.log(LogLevel.WARN, "Property ${propertyName} is not defined!")
}
} else if (property.isEmpty()) {
exists = false
if (warn) {
project.logger.log(LogLevel.WARN, "Property ${propertyName} is empty!")
}
}
if (!exists) {
project.setProperty(propertyName, defaultValue.toString())
}
}

void assertEnvironmentVariable(String propertyName) {
def property = System.getenv(propertyName)
if (property == null) {
throw new GradleException("System Environment Variable $propertyName is not defined!")
}
if (property.isEmpty()) {
throw new GradleException("Property $propertyName is empty!")
}
}
Loading

0 comments on commit bdb5d0c

Please sign in to comment.