Skip to content

Commit

Permalink
Initial commit of minecraft multithreading mod
Browse files Browse the repository at this point in the history
Initial release support 1.16.1 and 1.15.2, and allows for the parallelisation of
worlds, entities, tile entities, and environment ticks
  • Loading branch information
jediminer543 committed Aug 6, 2020
0 parents commit bb288c8
Show file tree
Hide file tree
Showing 34 changed files with 4,066 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Disable autocrlf on generated files, they always generate with LF
# Add any extra files or paths here to make git stop saying they
# are changed when only line endings change.
src/generated/**/.cache/cache text eol=lf
src/generated/**/*.json text eol=lf
78 changes: 78 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Build Directories #
#####################
# Directories with built content - not needed
/bin
/build

# Gradle #
##########
# Ignores all gradle files
/.gradle

# Git Stuff #
#############
# Removes strange git stuff such as temporary markdown previews.
/.README.md.html

# Eclipse #
###########
# Project configuration should be handled by gradle
# USE gradle:
.project
.classpath
/.settings

# Idea #
########
# Idea project config
# Idea users should target the project as a gradle project
*.iml
/.idea

# Java #
########
# Error files
hs_err_pid*.log
replay_pid*.log
*.class

# File Changes#
###############
# Hides files that have been renamed
# And backups of files
*.old
/*.old
*.bak
/*.bak

# FORGE GRADLE DEFAULTS #
#########################
# eclipse
bin
*.launch
.settings
.metadata
.classpath
.project

# idea
out
*.ipr
*.iws
*.iml
.idea

# gradle
build
.gradle

# other
eclipse
run

# Files from Forge MDK
forge*changelog.txt

# OTHER STUFF #
###############
# TODO
21 changes: 21 additions & 0 deletions LICENCE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Copyright (c) 2020, jediminer543

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76 changes: 76 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# MCMT - Minecraft Multi-Threading Mod

This is a mod for Minecraft (forge) versions 1.15.2 and 1.16.1 that enables multithreading

Currently it supports multithreading worlds, entities, tile entities, and environment ticks;
under testing it has appeared to work with mods.

Under single player testing, there is a nominal drop of 20-50% in tps enabled vs disabled and little measurable difference between disabled and not installed. Note: this is a processing side (i.e. either internal or dedicated server) mod and is unlikely cause any increase in framerates.

Also note that this WILL allow vanilla clients to connect to a server with just this mod and forge installed.

## IMPORTANT NOTICE

This fecks around with a LOT of minecraft's internal processing loops. If you are using this with any other mods; it may break. If you do something in vanilla, it might still break. It might break simply by you looking at it. It is almost impossible to test every possible interaction that CAN occur; all I can say is that it's worked in every case I've tested.

DO NOT, under any circumstances, report errors under this mod back to the mod author unless they have EXPLICITLY stated they are attempting to support it. Should mod devs wish to support this in any way, please yell so I can add registration apis.

TO MODDERS: This mod logs at warn level to the log saying it is installed every ~3 minutes and that the logs are invalid. It should be really obvious.

## Installing

Simply install the jar like you normally would any other mod; it's that simple.

There are different jars for 1.15.2 and 1.16.1 as while exactly 1 method thing changed to break transferability, there is no way for me to deal with it in a single jar. So make sure you get the right one.

## How it works

The normal minecraft server loop is:

```py
def tick() :
for world in worlds:
# random stuff
for chunk in world.loadedchunks:
chunk.tickEnvironment()
# random stuff
for entity in world.entities:
entity.tick()
for tileEntity in world.tileEntities:
tileEntity.tick()
```

All this mod does is parallelise each of these loops these loops. The vast majority of the performance (at least in my testing) was gained from parallelising entites.

Each one of the above loops is paralelised, and each one is toggleable.

To make this parallelisation work, there are a lot of patches to the minecraft core code to avoid concurrent access to non-concurrent objects (curse ye fastutil) or to replace them with a working concurrent alternative.

Further, this mod adds it's own chunk caching into the mix, in order to provide paralellised access to chunks; this does mean it may consume some more memory though.

I'll attempt to add more documentation as time goes by on how this works on the gritty internal level.

## Compiling

TODO: write properly

In summary:

Get a download of the repo:

`git clone [the url of the page you are on now]`

(Or download a zip and unzip it; it's up to you)

Open the directory containing it in a command line and run:

`./gradlew build`

The resulting jar will be present in `./build/libs/`

## TODO LIST

- Add config for specifying classes/packages that can/cant multithread
- Parallelise more stuff
- Hack the planet
- Document everything so it's reproducable
147 changes: 147 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

version = '0.9.7'
group = 'org.jmt.mcmt' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'jmt_mcmt'

sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.

println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
mappings channel: 'snapshot', version: '20200723-1.16.1'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.

accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')

// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')

// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'

// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'

mods {
examplemod {
source sourceSets.main
}
}
}

server {
workingDirectory project.file('run')

// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'

// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'

mods {
examplemod {
source sourceSets.main
}
}
}

data {
workingDirectory project.file('run')

// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'

// Recommended logging level for the console
property 'forge.logging.console.level', 'debug'

args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/')

mods {
examplemod {
source sourceSets.main
}
}
}
}
}

dependencies {
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft 'net.minecraftforge:forge:1.16.1-32.0.106'

// You may put jars on which you depend on in ./libs or you may define them like so..
// compile "some.group:artifact:version:classifier"
// compile "some.group:artifact:version"

// Real examples
// compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
// compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env

// The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'

// These dependencies get remapped to your current MCP mappings
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'

// For more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html

}

// Example for how to get properties into the manifest for reading by the runtime..
jar {
manifest {
attributes([
"Specification-Title": "jmt_mcmt",
"Specification-Vendor": "jmtmakesthings",
"Specification-Version": "1", // We are version 1 of ourselves
"Implementation-Title": project.name,
"Implementation-Version": "${version}",
"Implementation-Vendor" :"jmtmakesthings",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
}
}

// Example configuration to allow publishing using the maven-publish task
// This is the preferred method to reobfuscate your jar file
jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
//publish.dependsOn('reobfJar')

publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
}
}
repositories {
maven {
url "file:///${project.projectDir}/mcmodsrepo"
}
}
}
4 changes: 4 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 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.
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
Loading

0 comments on commit bb288c8

Please sign in to comment.