Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ replay_*.log
# include the music pack on github, not sure why I added this originally but adding it back now
# src/main/resources/musicpack/music/

issues.github-issues

151 changes: 151 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,154 @@ Reactive Music trades Minecraft's default music for something dynamic, reactive,
Reactive Music is based off a music pack I originally made for the Ambience mod back in 1.12. Now rebuilt to be a standalone mod for modern minecraft.

Discord: https://discord.gg/vJ6BCjPR3R

# ⚠️ This is an alpha experimental fork of Reactive Music.

New features were added, and the codebase was _**heavily**_ refactored with a lot of changes to internals. And also a whole lot of Javadocs comments for convenience and hopefully, a quicker adoption and improvement of this refreshed codebase that will allow a new ecosystem of **mods made for other mods** using the powerful new tools and systems available to developers through Reactive Music's Songpack & Event system.

Keep reading for a quick overview of the changes and additions.

<details>
<summary>
<h2>Code abstraction</h2>
</summary>

The codebase of Reactive Music `v1.x.x` was monolithic in various places, making it difficult to alter the main flow of the code or add features. I have aimed to improve developer experience through the following changes:

- The built-in events were moved to the new plugin system, allowing logic to be worked on within a final plugin class - making it easier to expand on these features and add new ones.
- The core logic behind the songpack loading & selection systems have been extracted into various new classes, making it easier to reimplement utility methods or hook into their logic at various points in the flow.

</details>
<details>
<summary>
<h2>Audio subsystem</h2>
</summary>

The `PlayerThread` class was a single instance of an audio player - which did it's job very well. But also with heavy restriction. Now, audio players and threads are created through `PlayerManager` classes, which handle tick-based fading, support making external calls, and more importantly - allow *multiple audio streams to exist.* These new instances are fully configurable, and allow for a deeper dive into Reactive Music not only as an event based *music* system for Minecraft, but basically an event based *sound engine*.

Some ideas that I have personally planned using this new functionality:

- Right clicking mobs with an empty hand plays an audio dialogue.
- Various actions the player may randomly trigger self-talk dialogue.
- Adding more immersive sounds to various objects.
- Fire gets louder the more things that are on fire.
- ^ in the same way - more immersive water ambience near specific biomes.

</details>
<details>
<summary>
<h2>API entrypoint</h2>
</summary>

Having a single entry point into Reactive Music's systems means it's easier to modify functionality, or hook into. This also makes developing new plugins for Reactive Music fairly straightforward - with the goal of making it easy to create new functionality around the songpack and event system.

As this fork of the mod is in an experimental alpha state, the API may undergo breaking changes at any time. Be prepared for the possibility of having to refactor your code on new feature releases or API updates.

</details>
<details>
<summary>
<h2>ReactiveMusicPlugin.java</h2>
</summary>

The main addition to this version of Reactive Music is the powerful plugin system. Using a service loader pattern, Reactive Music can now import external classes which follow the structure of the new `ReactiveMusicPlugin` class. To see examples of how this system works, take a look at the code for the built-in events now found in `plugins/`

</details>

---

# Changelog 💃 09.09.25

Changes:

* New `class` based command handler structure for client commands.
* Added various new commands, useful for debugging or to aid in songpack creation.

---
<details>
<summary>[ 09.09.25 ]</summary>

Changes:

* New `class` based command handler structure for client commands.
* Added various new commands, useful for debugging or to aid in songpack creation.

</details>

<details>
<summary>[ 09.08.25 ]</summary>

Changes:

* New `class` -> `RMGainSupplier` for usage in the map of gain suppliers in the player implementation.
* New API interface `GainSupplier`.
* Changed `requestGainRecompute()` in `RMPlayer` to use gain suppliers instead of hardcoded values.
* Overlay built-in plugin and Minecraft jukebox ducking now uses gain suppliers in the primary audio player.

</details>

<details>
<summary>[ 09.05.25 ]</summary>

Changes:

* Changed the final plugin class' API from an `interface` to a `class` to use `extends` instead of `implements`
* New `class` -> `RMPluginIdentifier` instanced by plugins on construction
* New `class` -> `RMEventRecord` which holds the registrar plugin's `RMPluginIdentifier`
* New API interfaces `EventRecord` and `PluginIdentifier`
* Changed the `Map` in `RMSongpackEvent` to take types `<EventRecord, Boolean>`
* Code adjusted to use `EventRecord` instead of `SongpackEvent` where applicable.

</details>

<details>
<summary>[ 09.01.25 ]</summary>

Fixes:

* Whoops! That was really broken, wasn't it?

</details>
<details>
<summary>[ 08.31.25 ]</summary>

Changes:

* API handles have been modified.
* Some redundant methods removed.

</details>
<details>
<summary>[ 08.26.25 ]</summary>

Fixes:

* OverlayTrackPlugin (Built-in) now properly *doesn't* stop the primary music player, by keeping `currentEntry` and disabling parts of `ReactiveMusicCore`. It's a bit coupled for now, but the plan is to clean this up and use it as a base for more expandability through the API.

Changes:

* API overhaul, consumer vs internal boundary is clearer and cleaner.
* Lots of filename changes because of the above point.

</details>
<details>
<summary>[ 08.21.25 ]</summary>
Fixes:

* Implemented a workaround for a bug where the audio player's gain was not set correctly before playing. The audio player is now primed with a small bit of silence before receiving samples.

</details>
<details>
<summary>[ 08.20.25 ]</summary>

Fixes:

* Fixed an issue that caused the core logic not to switch to a new song after a song had completed.

Changes:

* `currentSong` and `currentEntry` are now accessible through the API.
* Added a `skip` command, which *should* force the core logic to move on to the next song.

</details>


79 changes: 64 additions & 15 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
plugins {
id 'java'
id 'fabric-loom' version "${loom_version}"
id 'maven-publish'
}


loom {
runs {
client {
vmArgs "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
}
}
}


version = project.mod_version + "+" + project.minecraft_version
group = project.maven_group

Expand Down Expand Up @@ -89,6 +100,9 @@ java {

sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

jar {
Expand All @@ -97,20 +111,55 @@ jar {
}
}

// configure the maven publication
// Ensure Loom’s remapped outputs get published
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
publications {
mavenJava(MavenPublication) {
groupId = project.group
artifactId = project.archivesBaseName
version = project.version

artifact(remapJar) {
builtBy remapJar
}
artifact(remapSourcesJar) {
builtBy remapSourcesJar
}

pom {
name = project.archivesBaseName
description = 'Mocha (re)Mix of Reactive Music!'
url = 'https://github.com/rocamocha/ReactiveMusic'

licenses {
license {
name = 'GPLv3'
url = 'https://opensource.org/license/gpl-3-0'
}
}
developers {
developer {
id = 'rocamocha'
name = 'Jeric Rocamora'
}
}
scm {
url = 'https://github.com/rocamocha/ReactiveMusic'
connection = 'scm:git:https://github.com/rocamocha/ReactiveMusic.git'
developerConnection = 'scm:git:ssh://git@github.com/rocamocha/ReactiveMusic.git'
}
}
}
}
repositories {
maven {
name = "GitHubPackages" // can be anything
url = uri("https://maven.pkg.github.com/rocamocha/ReactiveMusic")
credentials {
username = System.getenv("GITHUB_ACTOR") ?: project.findProperty("gpr.user")
password = System.getenv("GITHUB_TOKEN") ?: project.findProperty("gpr.key")
}
}
}
}

// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
}
63 changes: 63 additions & 0 deletions docs/PLUGIN API/Beginner's-Guide-to-Plugin-Development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
In this section I will do my best to provide instruction, as well as recommendations, in how to start developing for Reactive Music from scratch.

# Getting Started
To start developing for Reactive Music, you will need a few things.

1. Your preferred text editor or IDE.
2. The Reactive Music `.jar` files.
3. A valid Fabric Minecraft project setup.
4. An idea for your plugin.
5. (Optionally) The `.jar` files for any other mods of which you will be accessing their API's.

## Setting up your IDE
Let's start by getting your IDE set up!

IDE stands for Integrated Development Environment.

It’s a software application that provides developers with a comprehensive set of tools to write, test, and debug code all in one place. Instead of using separate tools for editing, compiling, debugging, and version control, an IDE integrates them into a single interface.

There are many different IDE's out there - for today, I will recommend using VSCode. It's well adopted, feature full, and relatively easy to learn - in part because it's so widely used.

Go ahead and install an IDE then move on to the next step.

## Obtaining a Fabric mod template
Next we'll need to load up a project template onto your system. This is where the code for your plugin will live. You can select and download an official Fabric project template [here](https://fabricmc.net/develop/template/). Make sure to select the correct version of minecraft.

At this point, it is recommended to also get familiar with and setup a version control system such as [git](https://git-scm.com).

## Importing the builds into your environment
With a project template loaded, and your IDE fired up, you're almost ready to start developing.

Download the `.jar` files for the version of Reactive Music you want to develop for and copy them into a new folder in your project's root directory.

From here, you'll need to update your `build.gradle` file to include the `.jar` files. Find a block that looks like this:
```gradle
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

// Fabric API. This is technically optional, but you probably want it anyway.
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
```
Add the paths to the `.jar` files you copied - for example, I like to keep my `.jar` files in a folder labeled `libs/`:
```gradle
// ReactiveMusic API jar in libs/
modCompileOnly files("libs/reactivemusic-2.0.0-alpha.0.1+1.21.jar")

// Immersive Aircraft jar in libs/
modCompileOnly files("libs/immersive_aircraft-1.3.3+1.21.1-fabric.jar")
```

To keep it simple, if you're using VSCode - let's just close VSCode from here and reopen your project. This will get everything fired back up again so that VSCode will give you autocomplete suggestions - and will also let you compile! This is very important!

## Developing your plugin
If you've made it to this point - congratulations! You're almost officially a Minecraft modder 😎 Take a look at some other plugins for examples on how to structure your codebase, and different features you can add or expand on. This is where it gets really complicated - so at this point you're past being a beginner if you can make it to the next step - Good luck, and have fun 💃

Make sure to read [[this overview|Overview of the API]] to get an idea of how Reactive Music's systems work and what you need to do to have Reactive Music import your plugin.

## Building your plugin
Assuming you've done everything right, and your plugin's code is valid - go into the terminal portion of your IDE and use the command `gradlew build`
You'll be able to find your fresh `.jar` in `build/libs/` if it compiles. Install that into your Minecraft `mods` folder and test out your plugin!
23 changes: 23 additions & 0 deletions docs/PLUGIN API/Overview-of-the-API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Importing the API package gives you access to important classes and interfaces you'll need to start developing a Reactive Music plugin, or to hook into some of Reactive Music's core features as a mod developer.

```java
import circuitlord.reactivemusic.api;
```

# [[ReactiveMusicAPI]]
This class is the main entrypoint for Reactive Music developers. You'll find many useful methods and object references that you can implement to unlock the full immersive audio potential of your mod or plugin!

# [[ReactiveMusicPlugin]]
This is the service provider interface surface for the final class of a plugin, which should be configured to be imported by the service loader. It includes various `default` method calls meant to be overriden that are called at various points throughout Reactive Music's main flow.

## ⚠️ _Setting up your plugin for import!_
---
_For Reactive Music to recognize your plugin, you must declare it in the `resources` folder of your project. Create the directory `resources/META-INF` and create the file `circuitlord.reactivemusic.api.ReactiveMusicPlugin`<br>
<br>
Declare the package of your final plugin class extending `ReactiveMusicPlugin` like so:_
```
yourname.yourmod.someplace.YourPluginClass
```



Loading