TimeLib is a Minecraft modding library for Forge that lets you control game time.
Time is a very powerful game aspect that is often neglected. Changing how time behaves has the potential to dramatically alter game experience. For example, longer days and night could give players a greater sense of adventure by promoting immersion over fast-paced action, slow-motion effects applied in critical moments of battle could create a great feeling of excitement.
Through the use of Mixin and a simple to use API to configure various time related settings TimeLib gives developers the tools they need to create game changing mods.
-
Allows you to set game tick rate resulting in slower or faster movements and animations including all mobs and players, but does not affect the camera.
-
Allows you to set time cycle speed and control how fast days and nights last.
Each repository production and maven artifacts release contains three jar
types that you can download:
-dev.jar
is a non-obfuscated version of the jar used by developers.-sources.jar
contains project source files used by developers.-.jar
is an obfuscated production-ready jar mostly used by players.
Developers will want either the dev or production jar (optionally) accompanied by sources jar to make reading and understanding the library code easier when working with their mods.
Players will want only the production jar found in the repository release section on Github which they should treat as a standard game mod (see installation section for more information).
TimeLib is hosted on JitPack so head over there and get the latest release.
Here is the recommended way of getting the library in your project:
// Definines where Gradle should look for declared dependencies
// Declare this AFTER the buildscript block (first script block)
// and BEFORE MinecraftForge Gradle plugin configuration
repositories {
...
maven { url 'https://jitpack.io' }
}
minecraft {
...
}
dependencies {
// Specify the version of Minecraft to use
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
// We need to compile with the api but don't need it during runtime
compileOnly "com.github.yooksi:TimeLib:${timeLibVersion}:api"
// We need the main jar during runtime but not when compiling
runtimeOnly "com.github.yooksi:TimeLib:${timeLibVersion}:dev"
}
Note that the timeLibVersion
property in this example was defined in gradle.properties
to make accessing and reading version numbers easier. You should update the property (or just replace the variable) to a fully qualified version of the library you want to use.
The example above would attempt to resolve the following artifacts from Jitpack:
-
API library module for other mods to interact with. We need this jar when we are writing and compiling our mod so we use the
compileOnly
strategy. It is also needed during runtime but it's already included in the dev jar which is on runtime classpath. -
Deobfuscated version of our mod built for use by developers (indicated by the
dev
classifier). The dependency will be exposed only during runtime because we added it toruntimeOnly
configuration.
Another way to get the library would be to use fg.deobf
right after declaring the configuration type to indicate that the production jar should be deobfuscated after being resolved. This is not necessary and just adds extra work during build phase and makes deal with manually attaching source files. This is why the project provides a compiled dev
jar.
This is the recommended way to obtain the production jar for library users.
Developers should only use this way if JitPack is not working or they feel adventurous.
Check the releases section in project repository page to get the latest release.
- Make sure you have a backward compatible Forge version installed.
- Place the mod
jar
in gamemods
folder as per standard mod installation. - Download a backward compatible version of MixinBootstrap from the releases section of the project repository page and place it in game
mods
folder alongside the modjar
as previously instructed.
Forge and Mixin are not compatible straight out of the box so they need a bit of help to work in production environment. MixinBootstrap does just that, it's only function is to enable Mixin to work with Forge, that's it.
If you are interested in learning more about Mixin environment read Introduction to Mixins: The Mixin Environment.
\tickrate set <rate>
- change tick rate to a desired value (min 0.1, max 500).slow
- 50% slower tick rate (10).normal
- game default value (20).fast
- 50% faster tick rate (30).
\tickrate reset
- resets tick rate to game default value (20).\timecycle speed <value>
- change the speed for day/night time cycle (min -72, max 72)slow
- skip 1 tick when updating day time (x2 longer cycle).normal
- do not skip ticks when updating day time (game default).fast
- add 1 additional tick when updating day time (x2 faster cycle).
The following section is a brief technical explanation of how TimeLib is able to slow down game time. It is written in hopes that some developers might find it useful when learning to work with Mixin. Note that the process used to accomplish this involves bytecode manipulation and as such is not recommended as a starting point for beginners to learn about Java or Forge.
- During runtime Mixin will redirect method flow at a particular point in
MinecraftServer.run()
method and inject a callback to itself. The point of injection is thewhile
loop that handles the server time calculation and determines when each tick should happen. - We then do a series of calculations and determine how much milliseconds passed this tick based on the
mspt
(milliseconds per tick) rate calculated from tick rate set by the player via game command. - From there it's only a matter of incrementing
serverTime
and setting when tasks will be completed (runTasksUntil
) with the calculated value. The rest of the replaced loop is pure vanilla code.
The steps above slow down server tick rate but unfortunately result in frame skipping when rendering. This is caused by the client timer not calculating elapsed ticks properly, and here is how we deal with that:
- During runtime Mixin will redirect field access of
tickLength
innet.minecraft.util.Timer
class to returnmspt
(milliseconds per tick) calculated from tick rate set by player via game command. - Special care needs to be taken when dealing with pistons (see issue #3).
- Clone the repository with Git to your local disk.
- Import the project using your preferred IDE (IntelliJ IDEA is recommended).
- Workspace should automatically be setup by gradle (dependencies, decompilation etc.)
- Run gradle task
getIntellijRuns
if you are using IntelliJ orgenEclipseRuns
if you are using Eclipse to generate your project run configurations. Here are examples of how to run the command:gradlew getIntellijRuns
on Windows../gradlew genEclipseRuns
on Linux.
- Run
gradlew build
to compile and obfuscate your mod as ajar
inbuild/libs/
.
- Unregkiller - for commissioning the creation of this mod.
- gnembon - for creating Carpet on which this mod is based of.
- MDC, MMD and Mixin community- for helping resolve technical issues.
This library is licensed under General Public License v3.0.
Software that depends on, is built upon or derived from this library is conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved.