Merge remote-tracking branch 'upstream/1.20.1/dev' into feat/multi-loader-1.21

This commit is contained in:
IThundxr 2025-01-17 19:45:53 -05:00
commit 402cc4d2e3
Failed to generate hash of commit
48 changed files with 795 additions and 344 deletions

View file

@ -44,6 +44,8 @@ jobs:
common/build/libs/
fabric/build/libs/
neoforge/build/libs/
vanillinFabric/build/libs/
vanillinForge/build/libs/
test:
strategy:
@ -63,15 +65,15 @@ jobs:
- name: Setup Environment Variables
run: |
echo "MOD_VERSION=$(grep '^mod_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
echo "MINECRAFT_VERSION=$(grep '^minecraft_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
echo "FABRIC_API_VERSION=$(grep '^fabric_api_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ' | sed 's/+.*//')" >> "$GITHUB_ENV"
- name: Move Test Mod and Flywheel into run/mods
# We don't want to recreate the jar name formatting so glob everything over then remove the sources and javadoc jars
run: |
mkdir -p run/mods
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}.jar run/mods
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}-testmod.jar run/mods
cp ${{ matrix.loader }}/build/libs/*.jar run/mods
rm -f run/mods/*-sources.jar run/mods/*-javadoc.jar
# Lock to a specific commit, it would be bad if the tag is re-pushed with unwanted changes
- name: Run the MC client

View file

@ -13,10 +13,6 @@ open class JarSetExtension(private val project: Project) {
return JarTaskSet.create(project, name, *sourceSetSet)
}
fun outgoing(name: String, vararg sourceSetSet: SourceSet): JarTaskSet {
return JarTaskSet.create(project, name, *sourceSetSet).also { it.createOutgoingConfiguration() }
}
val mainSet: JarTaskSet by lazy {
val jarTask = project.tasks.named<Jar>("jar")
val remapJarTask = project.tasks.named<RemapJarTask>("remapJar")

View file

@ -23,11 +23,11 @@ import org.gradle.language.jvm.tasks.ProcessResources
class JarTaskSet(
private val project: Project,
private val name: String,
private val jar: TaskProvider<Jar>,
private val sources: TaskProvider<Jar>,
private val javadocJar: TaskProvider<Jar>,
private val remapJar: TaskProvider<RemapJarTask>,
private val remapSources: TaskProvider<RemapSourcesJarTask>
val jar: TaskProvider<Jar>,
val sources: TaskProvider<Jar>,
val javadocJar: TaskProvider<Jar>,
val remapJar: TaskProvider<RemapJarTask>,
val remapSources: TaskProvider<RemapSourcesJarTask>
) {
fun publish(artifactId: String) {
@ -41,10 +41,21 @@ class JarTaskSet(
}
}
/**
* Create a new configuration that can be consumed by other projects, and export the base jar.
*/
fun createOutgoingConfiguration() {
fun outgoing(name: String) {
outgoingRemapJar("${name}Remap")
outgoingJar("${name}Dev")
}
fun outgoingRemapJar(name: String) {
val config = project.configurations.register(name) {
isCanBeConsumed = true
isCanBeResolved = false
}
project.artifacts.add(config.name, remapJar)
}
fun outgoingJar(name: String) {
val config = project.configurations.register(name) {
isCanBeConsumed = true
isCanBeResolved = false

View file

@ -1,30 +1,18 @@
package dev.engine_room.gradle.platform
import dev.engine_room.gradle.jarset.JarTaskSet
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import net.fabricmc.loom.task.RemapJarTask
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.*
import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.kotlin.dsl.assign
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.register
import org.gradle.kotlin.dsl.the
import java.io.File
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
open class PlatformExtension(val project: Project) {
var commonProject: Project by DependentProject(this.project)
var modArtifactId: String = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
var apiArtifactId: String = "flywheel-${project.name}-api-${project.property("artifact_minecraft_version")}"
private val commonSourceSets: SourceSetContainer by lazy { commonProject.the<SourceSetContainer>() }
fun setupLoomMod(vararg sourceSets: SourceSet) {
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
sourceSets.forEach(::sourceSet)
@ -56,52 +44,6 @@ open class PlatformExtension(val project: Project) {
}
}
fun compileWithCommonSourceSets(vararg sourceSets: SourceSet) {
project.tasks.apply {
withType<JavaCompile>().configureEach {
JarTaskSet.excludeDuplicatePackageInfos(this)
}
sourceSets.forEach {
val commonSourceSet = commonSourceSets.named(it.name).get()
named<JavaCompile>(it.compileJavaTaskName).configure {
source(commonSourceSet.allJava)
}
named<ProcessResources>(it.processResourcesTaskName).configure {
from(commonSourceSet.resources)
}
}
}
}
fun setupFatJar(vararg sourceSets: SourceSet) {
project.tasks.apply {
val extraSourceSets = sourceSets.filter { it.name != "main" }.toList()
val commonSources = sourceSets.map { commonSourceSets.named(it.name).get() }
named<Jar>("jar").configure {
extraSourceSets.forEach { from(it.output) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
named<Javadoc>("javadoc").configure {
commonSources.forEach { source(it.allJava) }
extraSourceSets.forEach { source(it.allJava) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
named<Jar>("sourcesJar").configure {
commonSources.forEach { from(it.allJava) }
extraSourceSets.forEach { from(it.allJava) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
}
}
fun setupTestMod(sourceSet: SourceSet) {
project.tasks.apply {
val testModJar = register<Jar>("testModJar") {
@ -124,20 +66,4 @@ open class PlatformExtension(val project: Project) {
}
}
}
private class DependentProject(private val thisProject: Project) : ReadWriteProperty<Any?, Project> {
private var value: Project? = null
override fun getValue(thisRef: Any?, property: KProperty<*>): Project {
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Project) {
this.value = value
thisProject.evaluationDependsOn(value.path)
}
override fun toString(): String =
"NotNullProperty(${if (value != null) "value=$value" else "value not initialized yet"})"
}
}

View file

@ -0,0 +1,182 @@
package dev.engine_room.gradle.subproject
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginExtension
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.*
import org.gradle.language.jvm.tasks.ProcessResources
open class SubprojectExtension(val project: Project) {
fun init(archiveBase: String, group: String, version: String) {
setBaseProperties(archiveBase, group, version)
setupJava()
addRepositories()
setupLoom()
setupDependencies()
configureTasks()
setupPublishing()
}
private fun setBaseProperties(archiveBase: String, group: String, version: String) {
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
val buildNumber = System.getenv("BUILD_NUMBER")
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
project.group = project.property(group) as String
project.version = "${project.property(version)}${versionSuffix}"
project.the<BasePluginExtension>().apply {
archivesName = "${archiveBase}-${project.property("artifact_minecraft_version")}"
}
}
private fun setupLoom() {
val loom = project.the<LoomGradleExtensionAPI>()
loom.silentMojangMappingsLicense()
}
private fun setupJava() {
val java_version: String by project
project.the<JavaPluginExtension>().apply {
val javaVersion = JavaVersion.toVersion(java_version)
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
withSourcesJar()
withJavadocJar()
}
}
private fun addRepositories() {
project.repositories.apply {
mavenCentral()
maven("https://maven.parchmentmc.org") {
name = "ParchmentMC"
}
maven("https://maven.tterrag.com/") {
name = "tterrag maven"
}
maven("https://www.cursemaven.com") {
name = "CurseMaven"
content {
includeGroup("curse.maven")
}
}
maven("https://api.modrinth.com/maven") {
name = "Modrinth"
content {
includeGroup("maven.modrinth")
}
}
}
}
@Suppress("UnstableApiUsage")
private fun setupDependencies() {
project.dependencies.apply {
val minecraft_version: String by project
val parchment_minecraft_version: String by project
val parchment_version: String by project
val loom = project.the<LoomGradleExtensionAPI>()
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
add("mappings", loom.layered {
officialMojangMappings()
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
})
add("api", "com.google.code.findbugs:jsr305:3.0.2")
}
}
private fun configureTasks() {
val java_version: String by project
project.tasks.apply {
// make builds reproducible
withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
// module metadata is often broken on multi-platform projects
withType<GenerateModuleMetadata>().configureEach {
enabled = false
}
withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
options.release = Integer.parseInt(java_version)
options.compilerArgs.add("-Xdiags:verbose")
}
withType<Jar>().configureEach {
from("${project.rootDir}/LICENSE.md") {
into("META-INF")
}
}
withType<Javadoc>().configureEach {
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
options.encoding = "UTF-8"
}
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
withType<ProcessResources>().configureEach {
inputs.properties(replaceProperties)
filesMatching(processResourcesExpandFiles) {
expand(replaceProperties)
}
}
}
}
private fun setupPublishing() {
project.the<PublishingExtension>().repositories.apply {
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
if (project.hasProperty("mavendir")) {
maven(project.rootProject.file(project.property("mavendir") as String))
}
}
}
}
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/mods.toml")
val processResourcesExpandProperties = listOf(
"mod_license",
"mod_sources",
"mod_issues",
"mod_homepage",
"flywheel_id",
"flywheel_name",
"flywheel_description",
"flywheel_version",
"vanillin_id",
"vanillin_name",
"vanillin_version",
"vanillin_description",
"flywheel_maven_version_range",
"flywheel_semver_version_range",
"minecraft_semver_version_range",
"minecraft_maven_version_range",
"fabric_api_version_range",
"neoforge_version_range",
)

View file

@ -3,183 +3,14 @@ package dev.engine_room.gradle.subproject
import dev.engine_room.gradle.jarset.JarSetExtension
import dev.engine_room.gradle.nullability.PackageInfosExtension
import dev.engine_room.gradle.transitive.TransitiveSourceSetsExtension
import net.fabricmc.loom.api.LoomGradleExtensionAPI
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.BasePluginExtension
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.api.tasks.bundling.AbstractArchiveTask
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.*
import org.gradle.language.jvm.tasks.ProcessResources
class SubprojectPlugin: Plugin<Project> {
override fun apply(project: Project) {
project.extensions.create("defaultPackageInfos", PackageInfosExtension::class.java, project)
project.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, project)
project.extensions.create("jarSets", JarSetExtension::class.java, project)
setBaseProperties(project)
setupJava(project)
addRepositories(project)
setupLoom(project)
setupDependencies(project)
configureTasks(project)
setupPublishing(project)
}
private fun setBaseProperties(project: Project) {
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
val buildNumber = System.getenv("BUILD_NUMBER")
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
project.group = project.property("group") as String
project.version = "${project.property("mod_version")}${versionSuffix}"
project.the<BasePluginExtension>().apply {
archivesName = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
}
}
private fun setupLoom(project: Project) {
val loom = project.the<LoomGradleExtensionAPI>()
loom.silentMojangMappingsLicense()
}
private fun setupJava(project: Project) {
val java_version: String by project
project.the<JavaPluginExtension>().apply {
val javaVersion = JavaVersion.toVersion(java_version)
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
withSourcesJar()
withJavadocJar()
}
}
private fun addRepositories(project: Project) {
project.repositories.apply {
mavenCentral()
maven("https://maven.parchmentmc.org") {
name = "ParchmentMC"
}
maven("https://maven.tterrag.com/") {
name = "tterrag maven"
}
maven("https://www.cursemaven.com") {
name = "CurseMaven"
content {
includeGroup("curse.maven")
}
}
maven("https://api.modrinth.com/maven") {
name = "Modrinth"
content {
includeGroup("maven.modrinth")
}
}
}
}
@Suppress("UnstableApiUsage")
private fun setupDependencies(project: Project) {
project.dependencies.apply {
val minecraft_version: String by project
val parchment_minecraft_version: String by project
val parchment_version: String by project
val loom = project.the<LoomGradleExtensionAPI>()
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
add("mappings", loom.layered {
officialMojangMappings()
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
})
add("api", "com.google.code.findbugs:jsr305:3.0.2")
}
}
private fun configureTasks(project: Project) {
val java_version: String by project
project.tasks.apply {
// make builds reproducible
withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
// module metadata is often broken on multi-platform projects
withType<GenerateModuleMetadata>().configureEach {
enabled = false
}
withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
options.release = Integer.parseInt(java_version)
options.compilerArgs.add("-Xdiags:verbose")
}
withType<Jar>().configureEach {
from("${project.rootDir}/LICENSE.md") {
into("META-INF")
}
}
withType<Javadoc>().configureEach {
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
options.encoding = "UTF-8"
}
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
withType<ProcessResources>().configureEach {
inputs.properties(replaceProperties)
filesMatching(processResourcesExpandFiles) {
expand(replaceProperties)
}
}
}
}
private fun setupPublishing(project: Project) {
project.the<PublishingExtension>().repositories.apply {
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
if (project.hasProperty("mavendir")) {
maven(project.rootProject.file(project.property("mavendir") as String))
}
}
project.extensions.create("subproject", SubprojectExtension::class.java, project)
}
}
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/neoforge.mods.toml")
val processResourcesExpandProperties = listOf(
"mod_id",
"mod_name",
"mod_description",
"mod_license",
"mod_sources",
"mod_issues",
"mod_homepage",
"mod_version",
"minecraft_semver_version_range",
"minecraft_maven_version_range",
"fabric_api_version_range",
"neoforge_version_range",
)

View file

@ -1,6 +1,15 @@
package dev.engine_room.gradle.transitive
import dev.engine_room.gradle.jarset.JarTaskSet
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.jvm.tasks.Jar
import org.gradle.kotlin.dsl.named
import org.gradle.kotlin.dsl.the
import org.gradle.language.jvm.tasks.ProcessResources
class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) {
internal val compileSourceSets = mutableSetOf<SourceSet>()
@ -19,14 +28,21 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
rootRuntime()
}
fun compile(vararg sourceSets: SourceSet) {
fun compileClasspath(vararg sourceSets: SourceSet) {
compileSourceSets += sourceSets
for (sourceSet in sourceSets) {
this.sourceSet.compileClasspath += sourceSet.output
}
}
fun runtime(vararg sourceSets: SourceSet) {
fun compileClasspath(project: Project, vararg sourceSets: String) {
val externalSourceSets = project.the<SourceSetContainer>()
for (name in sourceSets) {
this.sourceSet.compileClasspath += externalSourceSets.getByName(name).output
}
}
fun runtimeClasspath(vararg sourceSets: SourceSet) {
runtimeSourceSets += sourceSets
for (sourceSet in sourceSets) {
this.sourceSet.runtimeClasspath += sourceSet.output
@ -34,7 +50,107 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
}
fun implementation(vararg sourceSets: SourceSet) {
compile(*sourceSets)
runtime(*sourceSets)
compileClasspath(*sourceSets)
runtimeClasspath(*sourceSets)
}
fun from(otherProject: Project) {
from(otherProject, sourceSet.name)
}
fun from(otherProject: Project, vararg names: String) {
val otherSourceSets = otherProject.the<SourceSetContainer>()
from(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
}
fun from(vararg sourceSets: SourceSet) {
parent.project.tasks.apply {
named<JavaCompile>(sourceSet.compileJavaTaskName).configure {
sourceSets.forEach { source(it.allJava) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
named<ProcessResources>(sourceSet.processResourcesTaskName).configure {
sourceSets.forEach { from(it.resources) }
}
}
}
fun bundleFrom(otherProject: Project) {
bundleFrom(otherProject, sourceSet.name)
}
fun bundleFrom(otherProject: Project, vararg names: String) {
val otherSourceSets = otherProject.the<SourceSetContainer>()
bundleFrom(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
}
fun bundleFrom(vararg sourceSets: SourceSet) {
from(*sourceSets)
// The external sourceSets will be included in the jar by default since we bring it into the java compile task,
// however we need to make sure that the javadoc and sources jars also include the external sourceSets
bundleJavadocAndSources(*sourceSets)
}
fun bundleOutput(vararg sourceSets: SourceSet) {
bundleJavadocAndSources(*sourceSets)
parent.project.tasks.apply {
named<Jar>(sourceSet.jarTaskName).configure {
sourceSets.forEach { from(it.output) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
}
}
private fun bundleJavadocAndSources(vararg sourceSets: SourceSet) {
parent.project.tasks.apply {
named<Javadoc>(sourceSet.javadocTaskName).configure {
sourceSets.forEach { source(it.allJava) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
named<Jar>(sourceSet.sourcesJarTaskName).configure {
sourceSets.forEach { from(it.allJava) }
JarTaskSet.excludeDuplicatePackageInfos(this)
}
}
}
fun outgoing() {
outgoingClasses()
outgoingResources()
}
fun outgoingResources() {
val project = parent.project
val exportResources = project.configurations.register("${sourceSet.name}Resources") {
isCanBeResolved = false
isCanBeConsumed = true
}
val processResources = project.tasks.named<ProcessResources>(sourceSet.processResourcesTaskName).get()
project.artifacts.add(exportResources.name, processResources.destinationDir) {
builtBy(processResources)
}
}
fun outgoingClasses() {
val project = parent.project
val exportClasses = project.configurations.register("${sourceSet.name}Classes") {
isCanBeResolved = false
isCanBeConsumed = true
}
val compileTask = project.tasks.named<JavaCompile>(sourceSet.compileJavaTaskName).get()
project.artifacts.add(exportClasses.name, compileTask.destinationDirectory) {
builtBy(compileTask)
}
}
}

View file

@ -5,7 +5,7 @@ import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.SourceSet
open class TransitiveSourceSetsExtension(private val project: Project) {
open class TransitiveSourceSetsExtension(val project: Project) {
var compileClasspath: FileCollection? = null
var runtimeClasspath: FileCollection? = null

View file

@ -6,44 +6,54 @@ plugins {
id("flywheel.subproject")
}
subproject.init("flywheel-common", "flywheel_group", "flywheel_version")
val api = sourceSets.create("api")
val lib = sourceSets.create("lib")
val backend = sourceSets.create("backend")
val main = sourceSets.getByName("main")
val vanillin = sourceSets.create("vanillin")
transitiveSourceSets {
compileClasspath = main.compileClasspath
sourceSet(api) {
rootCompile()
outgoingClasses()
}
sourceSet(lib) {
rootCompile()
compile(api)
compileClasspath(api)
outgoing()
}
sourceSet(backend) {
rootCompile()
compile(api, lib)
compileClasspath(api, lib)
outgoing()
}
sourceSet(stubs) {
rootCompile()
outgoingClasses()
}
sourceSet(main) {
compile(api, lib, backend)
compileClasspath(api, lib, backend)
outgoing()
}
sourceSet(sourceSets.getByName("test")) {
implementation(api, lib, backend)
}
sourceSet(vanillin) {
rootCompile()
compileClasspath(api, lib)
outgoing()
}
}
defaultPackageInfos {
sources(api, lib, backend, main)
sources(api, lib, backend, main, vanillin)
}
jarSets {
// For sharing with other subprojects.
outgoing("commonApiOnly", api)
outgoing("commonLib", lib)
outgoing("commonBackend", backend)
outgoing("commonImpl", main)
// For publishing.
create("api", api, lib).apply {
addToAssemble()

View file

@ -15,11 +15,48 @@ public interface InstanceType<I extends Instance> {
*/
I create(InstanceHandle handle);
/**
* The native memory layout of this instance type.
*
* <p>This layout determines what fields are made available to the instance type's shaders
* as well as determining how the fields are arranged in memory.
*
* @return The layout of this instance type.
*/
Layout layout();
/**
* The writer of this instance type.
*
* <p>The writer of an InstanceType is responsible for translating java instance objects
* into contiguous native memory. The instance writer must write to the given pointer
* according to the layout of this instance type.
*
* <p>It is undefined behavior to write outside the half closed range
* {@code [ptr, ptr + layout().byteSize())}.
*
* @return The writer for this instance type.
*/
InstanceWriter<I> writer();
/**
* <p>The vertex shader of an InstanceType is responsible for transforming vertices from mesh
* space to world space in whatever way the instance type requires.
*
* @return The vertex shader for this instance type.
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation vertexShader();
/**
* The cull shader of this instance type.
*
* <p>The cull shader of an InstanceType is responsible for transforming bounding spheres from mesh
* space to world space, such that a mesh contained by the input bounding sphere and transformed
* by the vertex shader would be contained by the output bounding sphere.
*
* @return The cull shader for this instance type.
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation cullShader();
}

View file

@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
import net.minecraft.resources.ResourceLocation;
/**
* A shader that decides what colors should be discarded in the fragment shader.
*/
public interface CutoutShader {
/**
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation source();
}

View file

@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
import net.minecraft.resources.ResourceLocation;
/**
* A shader that controls the fog effect on a material.
*/
public interface FogShader {
/**
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation source();
}

View file

@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
import net.minecraft.resources.ResourceLocation;
/**
* A shader that controls the GPU-based light on a material.
*/
public interface LightShader {
/**
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation source();
}

View file

@ -2,8 +2,17 @@ package dev.engine_room.flywheel.api.material;
import net.minecraft.resources.ResourceLocation;
/**
* A vertex and fragment shader pair that can be attached to a material.
*/
public interface MaterialShaders {
/**
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation vertexSource();
/**
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
*/
ResourceLocation fragmentSource();
}

View file

@ -42,6 +42,10 @@ public class InstancedDraw {
return deleted;
}
public MeshPool.PooledMesh mesh() {
return mesh;
}
public void render(TextureBuffer buffer) {
if (mesh.isInvalid()) {
return;

View file

@ -64,6 +64,9 @@ public class InstancedRenderStage {
uploadMaterialUniform(program, material);
program.setUInt("_flw_vertexOffset", drawCall.mesh()
.baseVertex());
MaterialRenderState.setup(material);
Samplers.INSTANCE_BUFFER.makeActive();

View file

@ -14,6 +14,7 @@ public enum DebugMode implements StringRepresentable {
LIGHT_COLOR,
OVERLAY,
DIFFUSE,
MODEL_ID,
;
public static final Codec<DebugMode> CODEC = StringRepresentable.fromEnum(DebugMode::values);

View file

@ -14,7 +14,7 @@ in vec2 _flw_crumblingTexCoord;
#endif
#ifdef _FLW_DEBUG
flat in uint _flw_instanceID;
flat in uvec2 _flw_ids;
#endif
out vec4 _flw_outputColor;
@ -79,7 +79,7 @@ void _flw_main() {
color = vec4(flw_vertexNormal * .5 + .5, 1.);
break;
case 2u:
color = _flw_id2Color(_flw_instanceID);
color = _flw_id2Color(_flw_ids.x);
break;
case 3u:
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
@ -93,6 +93,9 @@ void _flw_main() {
case 6u:
color = vec4(vec3(diffuseFactor), 1.);
break;
case 7u:
color = _flw_id2Color(_flw_ids.y);
break;
}
#endif

View file

@ -72,10 +72,10 @@ mat3 _flw_normalMatrix;
#endif
#ifdef _FLW_DEBUG
flat out uint _flw_instanceID;
flat out uvec2 _flw_ids;
#endif
void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
void _flw_main(in FlwInstance instance, in uint stableInstanceID, in uint modelID) {
_flw_layoutVertex();
flw_instanceVertex(instance);
flw_materialVertex();
@ -96,6 +96,6 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
gl_Position = flw_viewProjection * flw_vertexPos;
#ifdef _FLW_DEBUG
_flw_instanceID = stableInstanceID;
_flw_ids = uvec2(stableInstanceID, modelID);
#endif
}

View file

@ -51,5 +51,5 @@ void main() {
FlwInstance instance = _flw_unpackInstance(instanceIndex);
_flw_main(instance, instanceIndex);
_flw_main(instance, instanceIndex, draw.vertexOffset);
}

View file

@ -10,6 +10,8 @@ uniform mat4 _flw_modelMatrixUniform;
uniform mat3 _flw_normalMatrixUniform;
#endif
uniform uint _flw_vertexOffset;
void main() {
_flw_unpackMaterialProperties(_flw_packedMaterial.y, flw_material);
@ -20,5 +22,5 @@ void main() {
_flw_normalMatrix = _flw_normalMatrixUniform;
#endif
_flw_main(instance, uint(gl_InstanceID));
_flw_main(instance, uint(gl_InstanceID), _flw_vertexOffset);
}

View file

@ -6,7 +6,6 @@ import org.slf4j.LoggerFactory;
import dev.engine_room.flywheel.api.Flywheel;
import dev.engine_room.flywheel.backend.FlwBackend;
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
public final class FlwImpl {
public static final Logger LOGGER = LoggerFactory.getLogger(Flywheel.ID);
@ -23,9 +22,6 @@ public final class FlwImpl {
// backend
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
// vanilla
VanillaVisuals.init();
}
public static void freezeRegistries() {

View file

@ -0,0 +1,5 @@
package dev.engine_room.vanillin;
public class Vanillin {
public static final String ID = "vanillin";
}

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import java.util.function.Consumer;

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import java.util.Calendar;
import java.util.EnumMap;

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import java.util.Set;
import java.util.function.Consumer;

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import org.joml.Matrix4f;

View file

@ -1,4 +1,4 @@
package dev.engine_room.flywheel.vanilla;
package dev.engine_room.vanillin.visuals;
import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder;
import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder;

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -7,6 +7,11 @@ plugins {
id("flywheel.platform")
}
val common = ":common"
val commonProject = project(common)
subproject.init("flywheel-fabric", "flywheel_group", "flywheel_version")
val api = sourceSets.create("api")
val lib = sourceSets.create("lib")
val backend = sourceSets.create("backend")
@ -18,17 +23,34 @@ transitiveSourceSets {
sourceSet(api) {
rootCompile()
from(commonProject)
}
sourceSet(lib) {
rootCompile()
compile(api)
compileClasspath(api)
from(commonProject)
}
sourceSet(backend) {
rootCompile()
compile(api, lib)
compileClasspath(api, lib)
from(commonProject)
}
sourceSet(stubs) {
rootCompile()
from(commonProject)
}
sourceSet(main) {
// Don't want stubs at runtime
compileClasspath(stubs)
implementation(api, lib, backend)
bundleFrom(commonProject)
bundleOutput(api, lib, backend)
}
sourceSet(testMod) {
rootCompile()
@ -38,19 +60,18 @@ transitiveSourceSets {
}
platform {
commonProject = project(":common")
compileWithCommonSourceSets(api, lib, backend, main)
setupLoomMod(api, lib, backend, main)
setupLoomRuns()
setupFatJar(api, lib, backend, main)
setupTestMod(testMod)
}
jarSets {
mainSet.publish(platform.modArtifactId)
mainSet.publish("flywheel-fabric-${project.property("artifact_minecraft_version")}")
mainSet.outgoing("flywheel")
create("api", api, lib).apply {
addToAssemble()
publish(platform.apiArtifactId)
publish("flywheel-fabric-api-${project.property("artifact_minecraft_version")}")
configureJar {
manifest {
@ -79,8 +100,13 @@ dependencies {
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
"forLib"(project(path = ":common", configuration = "commonLib"))
"forBackend"(project(path = ":common", configuration = "commonBackend"))
"forMain"(project(path = ":common", configuration = "commonImpl"))
"forApi"(project(path = common, configuration = "apiClasses"))
"forLib"(project(path = common, configuration = "libClasses"))
"forBackend"(project(path = common, configuration = "backendClasses"))
"forStubs"(project(path = common, configuration = "stubsClasses"))
"forMain"(project(path = common, configuration = "mainClasses"))
"forLib"(project(path = common, configuration = "libResources"))
"forBackend"(project(path = common, configuration = "backendResources"))
"forMain"(project(path = common, configuration = "mainResources"))
}

View file

@ -1,9 +1,9 @@
{
"schemaVersion": 1,
"id": "${mod_id}",
"version": "${mod_version}",
"name": "${mod_name}",
"description": "${mod_description}",
"id" : "${flywheel_id}",
"version" : "${flywheel_version}",
"name" : "${flywheel_name}",
"description" : "${flywheel_description}",
"authors": [
"Jozufozu",
"PepperCode1"

View file

@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"id" : "${mod_id}_testmod",
"name": "${mod_name} Test Mod",
"id" : "${flywheel_id}_testmod",
"name" : "${flywheel_name} Test Mod",
"version": "1.0.0",
"environment": "*",
"license": "${mod_license}",

View file

@ -1,15 +1,23 @@
org.gradle.jvmargs = -Xmx3G
org.gradle.daemon = false
# Mod metadata
mod_id = flywheel
mod_name = Flywheel
mod_version = 1.0.0-beta
mod_description = An overhauled entity and block entity rendering API.
# Common metadata
mod_license = MIT
mod_sources = https://github.com/Engine-Room/Flywheel
mod_issues = https://github.com/Engine-Room/Flywheel/issues
mod_homepage = https://github.com/Engine-Room/Flywheel
# Flywheel metadata
flywheel_id=flywheel
flywheel_name=Flywheel
flywheel_version=1.0.0-beta
flywheel_description=An overhauled entity and block entity rendering API.
# Vanillin metadata
vanillin_id=vanillin
vanillin_name=Vanillin
vanillin_version=1.0.0-beta
vanillin_description=Instanced rendering for entities and block entities via Flywheel.
# Vanillin dependencies
flywheel_maven_version_range=[1.0.0-beta,2.0)
flywheel_semver_version_range=>=1.0.0-beta <2.0.0
# Mod dependency declarations
minecraft_semver_version_range = >=1.21.1 <1.21.2
@ -37,5 +45,6 @@ iris_version = 1.8.0-beta.8+1.21.1
embeddium_version = 1.0.11+mc1.21.1
# Publication info
group = dev.engine_room.flywheel
flywheel_group=dev.engine_room.flywheel
vanillin_group=dev.engine_room.vanillin
artifact_minecraft_version = 1.21.1

View file

@ -7,6 +7,11 @@ plugins {
id("flywheel.platform")
}
val common = ":common"
val commonProject = project(common)
subproject.init("flywheel-forge", "flywheel_group", "flywheel_version")
val api = sourceSets.create("api")
val lib = sourceSets.create("lib")
val backend = sourceSets.create("backend")
@ -18,17 +23,32 @@ transitiveSourceSets {
sourceSet(api) {
rootCompile()
from(commonProject)
}
sourceSet(lib) {
rootCompile()
compile(api)
compileClasspath(api)
from(commonProject)
}
sourceSet(backend) {
rootCompile()
compile(api, lib)
compileClasspath(api, lib)
from(commonProject)
}
sourceSet(stubs) {
rootCompile()
from(commonProject)
}
sourceSet(main) {
compile(api, lib, backend)
compileClasspath(api, lib, backend)
bundleFrom(commonProject)
bundleOutput(api, lib, backend)
}
sourceSet(testMod) {
rootCompile()
@ -38,19 +58,18 @@ transitiveSourceSets {
}
platform {
commonProject = project(":common")
compileWithCommonSourceSets(api, lib, backend, main)
setupLoomMod(api, lib, backend, main)
setupLoomRuns()
setupFatJar(api, lib, backend, main)
setupTestMod(testMod)
}
jarSets {
mainSet.publish(platform.modArtifactId)
mainSet.publish("flywheel-forge-${project.property("artifact_minecraft_version")}")
mainSet.outgoing("flywheel")
create("api", api, lib).apply {
addToAssemble()
publish(platform.apiArtifactId)
publish("flywheel-forge-api-${project.property("artifact_minecraft_version")}")
configureJar {
manifest {
@ -91,8 +110,13 @@ dependencies {
modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
"forLib"(project(path = ":common", configuration = "commonLib"))
"forBackend"(project(path = ":common", configuration = "commonBackend"))
"forMain"(project(path = ":common", configuration = "commonImpl"))
"forApi"(project(path = common, configuration = "apiClasses"))
"forLib"(project(path = common, configuration = "libClasses"))
"forBackend"(project(path = common, configuration = "backendClasses"))
"forStubs"(project(path = common, configuration = "stubsClasses"))
"forMain"(project(path = common, configuration = "mainClasses"))
"forLib"(project(path = common, configuration = "libResources"))
"forBackend"(project(path = common, configuration = "backendResources"))
"forMain"(project(path = common, configuration = "mainResources"))
}

View file

@ -5,10 +5,10 @@ license = "${mod_license}"
issueTrackerURL = "${mod_issues}"
[[mods]]
modId = "${mod_id}"
version = "${mod_version}"
displayName = "${mod_name}"
description = "${mod_description}"
modId = "${flywheel_id}"
version = "${flywheel_version}"
displayName = "${flywheel_name}"
description = "${flywheel_description}"
logoFile = "logo.png"
authors = "Jozufozu, PepperCode1"
displayURL = "${mod_homepage}"
@ -19,19 +19,25 @@ config = "flywheel.backend.mixins.json"
[[mixins]]
config = "flywheel.impl.mixins.json"
[[dependencies.${mod_id}]]
[[dependencies.${ flywheel_id }]]
modId = "minecraft"
type = "required"
versionRange = "${minecraft_maven_version_range}"
side = "CLIENT"
[[dependencies.${mod_id}]]
modId = "neoforge"
type = "required"
[[dependencies.${ flywheel_id }]]
modId = "forge"
mandatory = true
versionRange = "${neoforge_version_range}"
side = "CLIENT"
[[dependencies.${mod_id}]]
[[dependencies.${ flywheel_id }]]
modId = "embeddium"
mandatory = false
versionRange = "[0.3.25,)"
side = "CLIENT"
[[dependencies.${ flywheel_id }]]
modId = "sodium"
type = "optional"
versionRange = "[0.6.0-beta.2,)"

View file

@ -1,6 +1,6 @@
{
"pack": {
"description": "${mod_name} resources",
"description": "${flywheel_name} resources",
"pack_format": 34
}
}

View file

@ -3,6 +3,6 @@ loaderVersion = "[0,)"
license = "${mod_license}"
[[mods]]
modId = "${mod_id}_testmod"
modId = "${flywheel_id}_testmod"
version = "1.0.0"
displayName = "${mod_name} Test Mod"
displayName = "${flywheel_name} Test Mod"

View file

@ -18,3 +18,5 @@ rootProject.name = "Flywheel"
include("common")
include("fabric")
include("neoforge")
include("vanillinForge")
include("vanillinFabric")

View file

@ -0,0 +1,56 @@
plugins {
idea
java
`maven-publish`
id("dev.architectury.loom")
id("flywheel.subproject")
id("flywheel.platform")
}
val common = ":common"
val platform = ":fabric"
subproject.init("vanillin-fabric", "vanillin_group", "vanillin_version")
val main = sourceSets.getByName("main")
platform {
setupLoomRuns()
}
transitiveSourceSets {
sourceSet(main) {
compileClasspath(project(platform), "api", "lib")
bundleFrom(project(common), "vanillin")
}
}
jarSets {
mainSet.publish("vanillin-fabric-${project.property("artifact_minecraft_version")}")
}
defaultPackageInfos {
sources(main)
}
loom {
mixin {
useLegacyMixinAp = true
add(main, "vanillin.refmap.json")
}
}
dependencies {
modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}")
compileOnly(project(path = common, configuration = "vanillinClasses"))
compileOnly(project(path = common, configuration = "vanillinResources"))
// JiJ flywheel proper
include(project(path = platform, configuration = "flywheelRemap"))
runtimeOnly(project(path = platform, configuration = "flywheelDev"))
}

View file

@ -0,0 +1 @@
loom.platform=fabric

View file

@ -0,0 +1,11 @@
package dev.engine_room.vanillin;
import dev.engine_room.vanillin.visuals.VanillaVisuals;
import net.fabricmc.api.ClientModInitializer;
public class VanillinFabric implements ClientModInitializer {
@Override
public void onInitializeClient() {
VanillaVisuals.init();
}
}

View file

@ -0,0 +1,34 @@
{
"schemaVersion" : 1,
"id" : "${vanillin_id}",
"version" : "${vanillin_version}",
"name" : "${vanillin_name}",
"description" : "${vanillin_description}",
"authors" : [
"Jozufozu",
"PepperCode1"
],
"contact" : {
"homepage" : "${mod_homepage}",
"sources" : "${mod_sources}",
"issues" : "${mod_issues}"
},
"license" : "${mod_license}",
"icon" : "logo.png",
"environment" : "client",
"entrypoints" : {
"client" : [
"dev.engine_room.vanillin.VanillinFabric"
]
},
"mixins" : [
],
"depends" : {
"minecraft" : "${minecraft_semver_version_range}",
"fabricloader" : ">=0.15.0",
"fabric-api" : "${fabric_api_version_range}",
"${flywheel_id}" : "${flywheel_semver_version_range}"
},
"breaks" : {
}
}

View file

@ -0,0 +1,67 @@
plugins {
idea
java
`maven-publish`
id("dev.architectury.loom")
id("flywheel.subproject")
id("flywheel.platform")
}
val common = ":common"
val platform = ":forge"
subproject.init("vanillin-forge", "vanillin_group", "vanillin_version")
val main = sourceSets.getByName("main")
platform {
setupLoomRuns()
}
transitiveSourceSets {
sourceSet(main) {
compileClasspath(project(platform), "api", "lib")
bundleFrom(project(common), "vanillin")
}
}
jarSets {
mainSet.publish("vanillin-forge-${project.property("artifact_minecraft_version")}")
}
defaultPackageInfos {
sources(main)
}
loom {
mixin {
useLegacyMixinAp = true
add(main, "vanillin.refmap.json")
}
forge {
// mixinConfig("flywheel.backend.mixins.json")
// mixinConfig("flywheel.impl.mixins.json")
}
runs {
configureEach {
property("forge.logging.markers", "")
property("forge.logging.console.level", "debug")
}
}
}
dependencies {
forge("net.minecraftforge:forge:${property("minecraft_version")}-${property("forge_version")}")
modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
compileOnly(project(path = common, configuration = "vanillinClasses"))
compileOnly(project(path = common, configuration = "vanillinResources"))
// JiJ flywheel proper
include(project(path = platform, configuration = "flywheelRemap"))
runtimeOnly(project(path = platform, configuration = "flywheelDev"))
}

View file

@ -0,0 +1 @@
loom.platform=forge

View file

@ -0,0 +1,23 @@
package dev.engine_room.vanillin;
import dev.engine_room.vanillin.visuals.VanillaVisuals;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@Mod(Vanillin.ID)
public class VanillinForge {
public VanillinForge() {
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
IEventBus modEventBus = FMLJavaModLoadingContext.get()
.getModEventBus();
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> clientInit(forgeEventBus, modEventBus));
}
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
VanillaVisuals.init();
}
}

View file

@ -0,0 +1,33 @@
modLoader = "javafml"
# The loader version doesn't matter. Modify the Forge and/or Minecraft version ranges instead.
loaderVersion = "[0,)"
license = "${mod_license}"
issueTrackerURL = "${mod_issues}"
[[mods]]
modId = "${vanillin_id}"
version = "${vanillin_version}"
displayName = "${vanillin_name}"
description = "${vanillin_description}"
logoFile = "logo.png"
authors = "Jozufozu, PepperCode1"
displayURL = "${mod_homepage}"
displayTest = "IGNORE_ALL_VERSION"
[[dependencies.${ vanillin_id }]]
modId = "minecraft"
mandatory = true
versionRange = "${minecraft_maven_version_range}"
side = "CLIENT"
[[dependencies.${ vanillin_id }]]
modId = "forge"
mandatory = true
versionRange = "${forge_version_range}"
side = "CLIENT"
[[dependencies.${ vanillin_id }]]
modId = "${flywheel_id}"
mandatory = true
versionRange = "${flywheel_maven_version_range}"
side = "CLIENT"

View file

@ -0,0 +1,6 @@
{
"pack": {
"description": "${vanillin_name} resources",
"pack_format": 15
}
}