Because JitPack breaks Gradle variants so we get the Java 17 jar even
when we use the Java 8 variant.
This works for building via Gradle. However it does not work for usage
from IntelliJ, where you must currently publishToMavenLocal ReplayStudio
and then depend on that version. Still looking for a better solution
there.
This because with 1.20.6, MC will require outbound messages to reach its
handlers to switch between protocol versions. So we need our drop
handler two be at the very end of the write processing chain.
We've done this ourselves only because it was easier at the beginning.
However with 1.20.5, Minecraft's packet decoding became substantially
more sophisticated, to the point that it's probably a bad idea to try
to do it ourselves.
Additionally, getting the packet ids, which we require for identifying
the packets which we want to decode, has becomes significantly more
difficult too, and this way it's a simple instanceof check.
We've done this ourselves only because it was easier at the beginning.
However by now (and especially with 1.20.5), Minecraft's packet decoding
has become substantially more sophisticated, to the point that it's
probably a bad idea to try to do it ourselves.
This commit gives back that responsibility to Minecraft by adding the
standard decoder (and encoder because it's required for proper
connection state management on modern versions) to our channel pipeline,
changes the full and the quick replay sender to send raw `ByteBuf`s into
the front of the channel, and moves the posititon of the full replay
sender in the channel pipeline such that it can see and modify packets
after Minecraft has decoded them.
- Upgrade Gradle to 8.7
- Increase build daemon max memory to 8GB because archloom can compile a lot
more projects at the same time.
- Disable Minecraft 1.8 (not 1.8.9) because archloom fails to set up for that
95a7c07 Process PlayerPositionRotation packet in SquashFilter
603bdce Create dedicated class for PacketPlayerPositionRotation
88343aa Fix incorrect order of ViaVersion-emitted packets
9ebaa97 Fix 1.20 to 1.20.2 ViaVersion conversion
c490e9f Update ViaVersion
bcccb2c Fix Reconfigure packets not being filtered out
a0df6c9 Fix ConfigFinish being emitted before other config packets
a672023 Separate pre-join-game packets from login-phase packets
a70161c Emit Reconfigure packet when required
074d78d Separate "emit first" list from "login phase" list
20a3bf9 Reorder loginPhase and configurationPhase code
We recently bumped the fabric-api version there, and newer versions of the v0
api just delegate to the v1 one now, so we need to include that there as well.
We'll use it in 1.20 mixins.
Unclear what minimal fabric-loader version it requires, so in the interest of
keeping older versions compatible with OptiFabric (old versions of which aren't
compatible with the latest fabric-loader), we'll add it to 1.16.4+ only.
The `Timeline` type is mutable, so we need to create a copy before we pass it to
GuiKeyframeRepository because we don't want anything stored in there (or more
specifically in render queue which can also be added to from that gui) to be
affected by subsequent changes.
It's only required for legacy Optifine doesn't even apply any more as of 1.18,
so we can just disable it on modern versions so it doesn't spam the log.
The respawn packet re-creates the player entity, so we need to re-send its
armor (and technically also the riding and sleeping state, though that probably
wouldn't ever have caused issues in practice because a respawn will implicitly
reset those, unlike your inventory which is preserved).
Because on 1.11+ a `null` item stack is not something that should exist.
This then also allows us to compare item stacks by value rather than only by
reference, potentially saving a few redundant entity equipment update
packets (but more importantly, also allows us to store a copy instead of the
original, which will be important for the next commit).
We cannot filter this packet purely on the netty thread because our filter
depends on the current camera position (if it's too far, we do want to teleport
it closer) and accessing the camera is only safe from the main thread.
Previously the second part had not been considered which could lead to race
conditions where the camera may not yet exist on the netty thread at time of
handling. These appear to have gotten the wholly inappropriate "just put a null
check around it" treatment, but that means that the filter sometimes doesn't
work (hence the bug report).
This commit changes handling such that all access to `allowMovement` is always
done on the main thread and then moves the filtering there as well. And
therefore filtering should now work properly.
Sharing the temporary `row` and `rowSwap` buffers between different calls to the
processor is not safe because it will be used by multiple threads.
As a result some of the rows in the image could randomly get corrupted.
This commit gets rid of the cached buffers (the value of which questionable
anyway) and simply re-uses the same code which other processors use.
No clue why `getResourceLocationForPlayerUUID` was implemented the way it was,
that commit dates back to 2015 (332c36a), but if the skin isn't loaded yet, it
won't load it, so sometimes it just won't show properly in first person and in
the Player Overview.
This commit just calls `AbstractClientPlayer.getSkinTexture` instead.
Unclear which MC versions are affected. At some point before 1.16.4 something
else was introduced which loads the skin for us, hence why modern versions were
not affected.
On my system, a single scroll tick results in 120 calls, which is fine for the
vanilla camera controller because it has a range of 2000, but the classic
controller only has a range of 36, making it impossible to select anything but
the extremes.
This commit changes the size of the range to match that of the vanilla controller.
That way we can simply use whatever version we want and aren't tied to the
version of lwjgl which MC provides.
This fixes the OpenEXR export on 1.19 crashing either due to the windows
workaround or due to differing lwjgl versions (depending on OS).
And also enables OpenEXR export on MC versions using lwjgl2 (1.12.2 and below).
Until now, recording worked by injecting right before the vanilla packet
handler. At that point it was receiving packet classes and had to re-encode them
to store them in the replay file. However, not all decoded packets can
necessarily be re-encoded without errors, requiring us to have a bunch of
workarounds.
This commit changes the way recording works by injecting right before the
decoder. It therefore receives the raw bytebufs and no longer has to deal with
the re-encode issue.
Terrain culling is only updated when the camera position or rotation changes.
For omnidirectional rendering, we don't change the camera directly though, we
rotate way earlier so we can consistently get before any other effects. As a
result, the terrain frustum culling wasn't updated between render passes
resulting in missing terrain.
This was largely masked by the fact that we used to call GameRenderer.onResize
every pass (even when the size hadn't changed) but fixing that made this issue
become apparent.
Instead of setting the the values via accessor and calling the handler directly.
This allows mods like ResolutionControl+ to properly resize its internal
framebuffers as well.
The only thing we care about is the framebuffer size, cause that will differ
between game and progress gui rendering. The window size will be the same (real)
size for both.
This makes it work more like regular 360 mode and is generally more compatible
because it doesn't require the frustum culling workarounds which the GPU
solution needs.
In particular, this fixes frustum culling with newer sodium versions (which no
longer use the vanilla intersection checking method) and fixes the clouds on
modern Iris (which seems to be using a different shader program for clouds).
9c5dec8 Fix writing of empty chunk load packet on 1.8.x (fixes#636)
3d8573f Fix writing of respawn packet on 1.8.x
39a85f7 Fix exception when cache file has invalid gzip header (fixes#535)
Fixes an issue where the world border would move at normal speed when speeding up or slowing down the replay, and also at an incorrect speed when rendering the replay, causing it to get out of sync with the rest of the world.
Co-authored-by: Jonas Herzig <me@johni0702.de>
Should be more compatible with mods which replace the entire renderHand
method (thereby making our mixin non-applicable), at least as long as these mods
check `renderHand` as well (Iris explicitly does).
This will become important once #638 is fixed.
This fixes the rotation of already existing entities that just got sent to the
client. Those get spawned with their rotation, which we didn't capture. This
commit fixes that by initializing our tracked rotation to NaN and returning the
original rotation until the tracked one is initialized (we do it this way rather
than initializing during the spawn packet handling because there are many spawn
packets, especially with modded, and we cannot possibly inject into all of
them).
This does not fix the rotation of newly placed entities (cause they seem to get
spawned with 0/0 and then get teleported to their correct rotation). The
previous commit fixed that case by capturing the rotation from the teleport
packet.
This fixes the rotation of newly placed entities (cause they seem to get spawned
with 0/0 and then get teleported to their correct rotation, which we didn't
capture).
This does not fix the rotation of already existing entities that just got sent
to the client, those already get spawned with their rotation, which we don't yet
capture. The following commit fixes that.
By updating the shadow plugin used in ReplayStudio.
java.lang.IncompatibleClassChangeError: Inconsistent constant pool data in classfile for class com/replaymod/replaystudio/lib/viaversion/libs/kyori/adventure/text/Component. Method 'boolean lambda$static$0(com.replaymod.replaystudio.lib.viaversion.libs.kyori.adventure.text.Component, com.replaymod.replaystudio.lib.viaversion.libs.kyori.adventure.text.Component)' at index 1064 is CONSTANT_MethodRef and should be CONSTANT_InterfaceMethodRef
This code supposedly meant for recording when a player was eating/blocking was
never needed to begin with cause the server echos all data in DataTracker
anyway, and now it broke the riptide animation because that's part of the
living flags as well but wasn't considered here, i.e. unconditionally
overwritten.
Forge naming strikes again, there's two different `updateCameraAndRender` in
1.14.4 forge, which lead us to use `updateCameraAndRender` for the older version
as well even though our desired method had a different name back then.
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).
To fix that, we now add the difference between the current `renderYaw` and the
desired one, modulo 360 (but with range (-180; 180]), to the current
`renderYaw`. That way we always take the short way round.
Additionally, because for rendering MC looks at the difference without modulo,
afterwards (and when a new `yaw` is set) we wrap the result around such that the
actual difference is always less than 180 and therefore rendered as intended.
This reverts commit 411eaa4ca8.
The given solution does not work in old versions because those did not use
`getYaw` for hand rendering. Even worse, their headYaw does wrap around and it
does it in a different way than their yaw value, giving a worse result than
without this commit.
MC uses the client-side position of an entity to determine whether it is inside
the simulation range and therefore whether it will get ticked. For some (most)
entities it interpolates the client-side position to match the server-side one
inside of the tick method... no prices for guessing where this goes wrong.
Somewhat similar to the issue we have with chunk unloads which we work around in
FullReplaySender but worse cause they'll get stuck if they ever leave the sim
range even for a single tick, rather then just when their chunk is unloaded.
Previously we injected it as a regular builtin resource pack (like the
Programmer Art pack) and hid it on the resource pack screen but this is bad for
several reasons. The most significant one being that it can be re-ordered and
makes the resource pack list ordering weird if you don't know that there is an
invisible pack there.
It also unnecessarily messes with other mods which make certain assumptions
about configurable resource packs (e.g. EBE, though in that case, it merely
triggers an existing bug in EBE).
We now instead inject it into the final resource pack list which gets
constructed from the configured packs, but never as a configurable pack itself.
The `yaw` value of non-client-players is constraint to [0; 360), so when that
boundary is crossed, the `renderYaw` starts interpolating to its goal the
incorrect way round (instead of crossing the 360 boundary as well).
Instead we now use the `headYaw` value, which does not wrap around and as such
does not have this issue.
By simply replacing the private field with a concrete type, so we do not need to
manually register one when constructing the gson instance (which is evidently
too easy to forget about).
No clue why this extra hud hiding was even there in the first place, the
renderer already takes care of properly hiding the hud (without hiding the
nametags) as it does for videos as well.
Either when it is cleared or when it is loaded from the keyframe repository, if
you exit the replay without any further changes, this used to not be saved.
That was never actually finished and we do not need to keep it around anymore.
Whether we add its successor once that is ready for production use remains to be
seen.
Similar to High Quality, it is too unpredictable, sometimes giving bad quality
and sometimes being unbearably slow. We should just encourage everyone to set
their bitrate manually.
Half the reason we swapped the render queue / settings parent relationship was
so we don't need to go through the settings screen to access the queue. But for
some reason I stopped half way through and didn't also move the "You need at
last two keyframes." popup. This commit rectifies that.
0e72e36 Add workaround for lack of way to determine global palette size
872bc75 Update vanilla global palette size
19d3dab Fix OOB when converting local palette storage to global palette (fixes#509)
c93a370 Fix incorrect packet release during SquashFilter.flush (fixes#490, fixes#492)
Iris derives that one from the frameStartNanos argument passed to the render
method and shaders usually use it to do animations. Prior to this commit we
always pass 0 which effectively froze any shader animations.
With this commit, we now compute the frameStartNanos based on the
FPS of the video we are rendering (so animations will happen in real time when
watching the video) or based on the time in the replay (so animations will
be influenced by playback speed / be frozen if the replay is frozen).
We default to the video time based approach because the replay time one may
produce undesirable results when it comes to things like motion blur and TAA.
In particular, Iris updates its frame counter and timer in the outer method, so
if we only call the inner one, then its shadows and sky will not update
properly.
Since the render method also renders the GUI, we set the current screen to null
and cancel the HUD during rendering. MC also clears the depth before rendering
the HUD, which we don't want because it breaks the depth map export, so we
cancel that as well.
This also allows Vanilla post-processing (aka Super Secret Settings, aka Vanilla
Shaders) as well as entity outlines to function properly cause those are applied
in that method as well.
Should have done this a long time ago but better late than never.
Closes#321
The previous one, blue with no shadow, had horrible contrast with the button
background and did not fit well with any of the other buttons.
Now it does (except that it's not yet in the 20-pixel width/height style).
Versions after 5.0.5 emit tsrg2 instead of tsrg, breaking anything which reads
those files (e.g. Mixin and the preprocessor), later versions even bump the
required Gradle version.
Since MC provides no reliable way to get the connection while still in the login
phase, Fabric API tries to determine it either from MinecraftClient's connection
field (for the integrated server) or from the ConnectScreen (for multiplayer).
However, neither is present during a replay, leading to the aforementioned
error.
To fix this, we store our ClientConnection in MinecraftClient's connection
field. This should have no significant effect on vanilla behavior.
Also remove the dead Forge 1.14 code which was in the same place.
Creates a dedicated folder for each video and does not depend on ffmpeg, just
like the EXRWriter (but supporting all MC versions).
Also does 32 bit depth export by chunking the 32-bit float into the 8-bit BGRA
component channels.
That is, most of the business code should not be aware that it is being compiled
to multiple versions even when it heavily interacts with MC, preprocessor
statements should be an escape hatch, not the norm.
Similarly, code should not be forced to do `MCVer.getWindow(mc)` instead of the
much more intuitive `mc.getWindow()`, and a new preprocessor (technically remap)
feature makes this possible by defining "search and replace"-like patterns (but
smarter in that they are type-aware) in one or more central places (the
"Patterns.java" files) which then are applied all over the code base.
In a way, this is another step in the automatic back-porting process where
preprocessor statements are used when we cannot yet do something automatically.
Previously we "merely" automatically converted between different mapping, this
new feature now also allows us to automatically perform simple refactoring
tasks like changing field access to a getter+setter (e.g. `mc.getWindow()`), or
changing how a method is called (e.g. `BufferBuilder.begin`), or changing a
method call chain (e.g. `dispatcher.camera.getYaw()`), or most other
search-and-replace-like changes and any combination of those.
The only major limitation is that the replacement itself is not smart, so
arguments must be kept in same order (or be temporarily assigned to local
variables which then can be used in any order).
Removes the need for //#if statements on each and every event handler.
Instead we now always use the equivalent Callback and have one central 1.12.2
class which forwards Forge events to the callbacks.
I don't think this sees sufficient use to justify updating.
Especially because it's non-trivial with forge's network changes.
Ping me if you actually used this.
a1f82a7 Properly handle same-dimension respawns in squash and quick mode (fixes#139, fixes#455)
7b84461 Fix NPE if there is a block change at time 0 (fixes#446)
ee9d7d5 Switch to LGPLv3+ as primary license
Clicking Cancel or Add to Queue does save them but clicking Render does not.
This is caused by the fact that the GuiRenderSettings are now a popup and no
longer their own screen, so to close them, we need to call its close method, not
close the entire screen.
Support remapping of mixin targets declared in static fields (specifically
`core.MixinKeyboardListener:ON_KEY_PRESSED`).
String literals in annotations can be specified in a static final field instead
of inline (so you can e.g. use the same literal in multiple places).
This commit adds support for remapping those external literals.
This happened to already be the case in 1.16.3 (because of another bug), this
commit makes it intentional and consistent across all versions.
Using the empty label over NONE or another label because it doesn't change the
width of the button and therefore fits nicer with all the other buttons.
For one, we have already switched to RGBA some time ago, so the name was
technically incorrect already.
But the main reason is that we'll want to use them for depth maps as well (and
potentially maybe even for HDR images if that's possible with canvas?).
This bug was introduced when we started to record the login phase because it
contains the UUID of the local player. In the replay case this will be the UUID
of the camera entity but also the one of the recording player, so if the
recording player despawns while it is being spectated (e.g. because of a
backwards jump), then the camera snaps onto itself and gets stuck in place until
one presses Shift.
In particular, we now position it relative to the realms (fallback to
multiplayer) button.
This removes the need for special-casing ModMenu and fixes compatibility with
Better Mod Button.
The texture of this button is based on the settings button of the ModMenu mod
and was originally under the MIT license "Copyright (c) 2018-2020 Prospector".
The derived version is licensed as any other file in this repository.
Previously you'd access the render queue from the render settings screen which
was arguably the wrong way around (e.g. you weren't able to access the queue
when your current keyframes were incorrect even if you only wanted to render
those in the queue).
Now the render button opens the queue which can open a new settings popup. To
save people who don't need the queue from always having to go through it, the
queue will immediately open a new settings popup if does not yet have any jobs.
Previously pressing F1 while the replay gui is focused (i.e. while the mouse is
visible) would toggle the global hudHidden state.
Now it only toggles the hidden state for the replay itself, allowing the
remainder to still be recorded with e.g. OBS where a full render isn't needed.
Basically the result of the Delombok function, except we use IntelliJ's equals,
hashCode and toString and don't re-organize imports (cause that breaks the
preprocessor) and a bunch of manual cleanup was necessary (and half the classes
weren't even converted).
This fixes both, replay-exclusive keybindings blocking vanilla ones as well as
vanilla keybindings blocking replay-exclusive ones.
The magic happens in Mixin_ContextualKeyBindings.
The fetching of the ticks variable was accidentally moved to before the timer
update while updating to 1.16, this caused the interpolation to be off by one
tick each frame in which the timer advances to the next tick.
For one, the forge handshake takes place *after* login phase (but before the
JoinGame packet), so we must ensure that the SquashFilter does not reorder
those.
Secondly, we were ignoring the initial packet (timestamp = 0) in marker
processor when it should have been passed to the SquashFilter. This was not an
issue before cause the SquashFilter did not rely on it. Now however the
SquashFilter needs to be able to see a login phase packet, so it knows that the
following packets till the JoinGame packet are part of the forge handshake.
In ReplayStudio:
20b5183 Fix forge handshake being reordered to after the JoinGame packet
Also need to update ModMenu because the version we depended on still bundled the
snapshot FAPI and that was only fine because we overwrote it with our version.
Configuring the annotation processor is done automatically as of IDEA 2020.1.
Run configs for 1.14+ versions should now be generated automatically once the
referenced PR is merged (or when using a local build of it).
fc8a66d Fix handling of view pos/dist packets in MC 1.14+ quick mode
2828174 Fix reading and writing of unload chunk packets pre-1.9 (fixes#210)
42bd0fe Fix map data being swallowed by squash filter (fixes#232)
MC stores server light data and only applies it during the next frame.
Therefore, if there is no frame between receiving the chunk and block changes in
it (like when jumping in replays), then the light update from the block change
gets lost.
This wasn't much of on issue because no tick events are fired normally while
paused. When seeking we do however manually run a tick for better result, and
this manual tick would cause this async sending code to run and seek wildly into
the future.
We used to include the raw jGui source in our jar and then had the main remapJar
task remap both of them to intermediary. This however does not work properly
when jGui needs additional mapping (e.g. because of mixin), resulting in
non-remapped mixins with fail to apply at runtime.
With this commit, we no longer include jGui in our raw jar and instead now have
shadowJar depend on jGui's remapJar task.
Aside from being best practice, this is necessary for the recording CRC to be
written to the replay file (cause that only happens on close).
Also potentially fixes https://github.com/ReplayMod/ReplayMod/issues/144 though
that should already be covered by ZipReplayFile tracking and closing all of its
`OutputStream`s before saving.
In particular:
- No longer generate any replays when auto-recording is off and recording is
never enabled from the ingame menu (fixes#138)
- Do not generate an additional empty replay file when recording was stopped in
ingame menu (fixes#147)
- only do squash if there are further output replays (fixes#142)
- Use the input file name as output file name even if there was a split (as long
as it's the only output file, e.g. because recording was never un-paused after
the split)
Similar to 3fedc22 in effect and cause. However tasks are executed, they just
cannot be submitted pre-1.14 because MC would continuously hold the lock on the
scheduledTasks queue for the entire renderVideo call.
We didn't used to do that because it would have required us to serialize and
then de-serialize as MCProtocolLib only to re-serialize each packet.
With ReplayStudio v2, we only have to convert to from MC's ByteBuf types to
ReplayStudio's ByteBuf (fairly trivial).
This also allows us to automatically make use of ReplayStudio's backwards
compatibility features: We didn't used to record the login phase pre-1.14 and we
still don't, so we now would have to inject a fake login packet (because we're
no longer generating legacy-version replay files) but ReplayOutputStream can
do that for us.
Without this commit, any pre-1.14 replays generated are unplayable due to the
missing LoginSuccess packet.
This used to be more of an issue in the past but `displaySizeChanged` has gotten
pretty cheap by now and not updating it will basically make the rendering GUI
useless once you resize even once.
This field is used to decide whether or not to render the inside-block overlay,
as such we want it to be set while we're in spectator mode).
This wasn't a problem before 1.15 because we also cancel the renderHand call
while we're in spectator mode and the same method which renders your hand also
renders the overlay, so we were inadvertently canceling that at the same time.
With 1.15, that's still the case except when using OF, which splits the method
apart by adding three boolean arguments indicating which part to execute.
We used to remap the old language key layout for inputs to the one used by
fabric but didn't consider that we might still be directly referencing the old
key somewhere else (e.g. for the Player Overview title).
With this commit, we retain the original and add the new mapping.
This intentionally breaks the mixin in a development environment but makes the
compiled jar work in a live environment (which is probably more useful given the
primary version is 1.15 now).
The task queue is executed by MC each frame, not just each tick, so we should do
so as well. Most async actions also rely on it to re-synchronize with the
rendering thread, e.g. skins won't load if we never poll the task queue.
This was caused by us setting `needsTerrainUpdate` to false during the shadow
pass in order to break out of the ForceChunkLoading loop (cause OF doesn't
update chunks during the shadow pass). However, this inadvertently caused the
chunk updates to be skipped during the normal pass as well if there didn't
happen to be another reasons for updating.
To fix this, we simply move the shadow pass check into the ForceChunkLoading
mixin and skip the entire loop during the shadow pass.
They ended up lingering around and breaking any further blocking operations,
resulting in random errors afterwards. And using them was really unnecessary
anyway.
In the case of #118, this was resulting in the EntityTrackerUpdate packet (which
contains info on which skin layers should be visible) sometimes ending up before
the SpawnPlayer packet, hence the players outer skin layers being invisible at
the start of the recording.
For some reason this applied fine in a development environment (even though the
method signature changed significantly), hence why I didn't notice it being
broken. It did not work (just like one would expect) in a live environment.
338c5a8 RandomAccessReplay: Handle light packets arriving after chunk packet
1658b5e SquashFilter: Fix entity delta position not being reset on teleport
There is no longer a dedicated "core" project where DEV_ENV would be defined,
instead whichever is the currently selected version automatically becomes the
main project using the main src folder.
See the linked commits in our FG fork for details.
`:1.8:setupDecompWorkspace` (and only that one) still fails with an unrelated
NPE which I can't be bothered to fix.
The new preprocessor version brings first-party support for fabric, in
particular for automatically fetching mappings loom and for
automatically remapping between MC versions via intermediary mappings.
This will come in handy when updating to 1.15.
It also supports automatic remapping between fabric and forge on the
same MC version (by going mcp<->srg<->mojang<->intermediary<->yarn).
Therefore this commit replaces the previous 1.13.2 (forge) subproject
with a 1.14.4-forge one. Instead of manually providing full mappings for
1.14.4-fabric to 1.13.2-forge and partial (classes) for 1.13.2-forge to
1.12.2-forge, we now only need partial (classes) for 1.12.2-forge to
1.14.4-forge and preprocessor will take care of the forge to fabric
step (in fact, our mapping file for that is currently completely empty).
In an attempt to write an IDE (IntelliJ) plugin for quicker and easier
working with the preprocessor (e.g. immediately mapping single files
from within the IDE, jumping between different versions for the same
file), the preprocessor gradle plugin declaration now requires you to
explicitly specify variables in the common.gradle and the overall
relationship between projects in the build.gradle (latter is required
anyway, so the plugin can know where it should map between forge and
fabric and which subprojects are which versions).
Since that necessitated some changes to the build.gradle file, I took
the opportunity to convert it to Kotlin. As such we now also use
Gradle's newer plugin-block with the pluginManagement-block instead of
manually declaring buildScript (not for the common.gradle though), which
imo is nicer anyway and comes with various advantages (see gradle docs).
There were also some remapping bugs fixed and some new ones
introduced (e.g. manually declared inner class mappings seem to no
longer function properly under certain conditions).
There's also support for remapping Kotlin now. Just saying.
Failure to load the entity tracker usually (not always) results in
`entityTracker` remaining to be `null`, so there has to be an additional
condition for aborting the thenRun-loadEntityTracker-…-recursion.
For some reason hypixel is sending duplicate entity meta data entries
in their spawn packets.
We'll now be ignoring all but the last one for each id (should match
how vanilla handles these).
Instead use NativeImage on 1.13+ via newly introduced Image class.
See Image docs for details.
Also fixes an issue with thumbnail taking on 1.13+: The original
ScreenshotHelper method is now async, luckily there's a sync
variant and as a bonus it directly returns a NativeImage so we can
skip having to read the screenshot from disk.
This has previously been fixed for quadruple-clicking on the replay
itself but for some reason has not been fixed for simply double-clicking
the "Load" button.
- Switch from ECJ to IDEA (with potential for kotlin)
- Can pull SRG mappings from FG, reducing amount of manual mappings (basically just class mappings and fixing errors in SRG mappings)
MC clears it scheduled tasks on disconnect. If we don't wait for
that to have happened on the async sender, then we might loose
some of the initial handshake packets (resulting in a dead lock in
fabric's registry syncing code).
The failing entity tracker really only breaks spectator keyframes.
This is also very desirable for minimal mode where entity tracker
failure is highly likely.
The preprocessor should have complained about these but it didn't for
some reason. This commit isn't fixing any imminent bug, it's just
precautionary (and required to compile once the preprocessor is fixed).
Turns out fabric's init runs earlier than forge so mc.options is still
null.
Instead we just store mc and access the options when needed (thanks to
the preprocessor that's even shorter than before).
While this commit also considerably simplifies/cleans the setup
method, the actual fix is that the networkManager is now added
to the channel pipeline with under the "packet_handler" key,
whereas before it was unnamed causing issues when transitioning
to the play state.
Before uploading to YouTube, convert all spherical non-mp4 files to mp4 to be able to inject metadata
Properly re-throw errors during the rendering pipeline
Allows very quick forwards and backwards jumping at the cost of only
replaying entity positions and block updates.
Still needs to be backported from 1.12.2 and contains FIXMEs
Re-creating the RenderChunk lost any custom data Optifine had in them which
resulted in NPEs.
The reason we re-create the RenderChunks is because otherwise, once it's
assigned an empty chunk once, it's not getting any further update even when
moving back to filled chunks. Since just calling setNeedsUpdate works as well,
this commit changes the whole mixin to doing that instead.
Well, looks like the jcenter repo doesn't care because the hash for
one of its jars has changed (a few bits in the jar were flipped).
Maven Central is still serving the original version, so we have to allow
both hashes.
The reobf task was not handling certain fields because it was missing
the respective classes on its classpath because we removed MC&deps
from the compile configuration.
The gson lib is provided by MC anyway.
Additionally, by shading it, we relocate the lib via the FG reobfJar
task which doesn't properly handle annotations causing the Mixin
lib's MixinConfig to no longer parse properly.
Primarily because of
1728e10 Default to no team color when receiving unknown values.
63e06fa Remove hard bitsPerEntry limit, enforce minimum of 4.
6de0593 Add CustomStatistic as fallback for custom or unimplemented statistic IDs.
The ReplaySender used to be started in async mode even before the call
to setup(). If the ReplaySender restarts the replay before the setup()
call finishes, that call may instead produce a NPE in
clientToServerHandshake().
To fix this race condition, the ReplaySender is always started in sync
mode and only switched to async after the setup() call.
setupTerrain will loop until (among other conditions) the chunksToUpdate set is
empty. However its size is never decreased during setupTerrain.
Having a (backwards) jump in time right before rendering the first frame would
reset the RenderGlobal due to the world change, leaving the chunksToUpdate set
empty to begin with and due to other changes, chunks are never inserted into it
during rendering (because they're always updated immediately).
The new screenshot feature and rendering a path that's in the future will not
trigger any world change, leaving the render process stuck in a life lock.
db1717f Merge branch 1.12-dev into 1.12.1-dev
d7dc2ba Merge branch 1.11.2-dev into 1.12-dev
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-dev
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
d7dc2ba Merge branch 1.11.2-dev into 1.12-dev
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-dev
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
b1c6098 Merge branch 1.11-dev into 1.11.2-dev
caf6051 Merge branch 1.9.4-dev into 1.11-dev
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
caf6051 Merge branch 1.9.4-dev into 1.11-dev
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
263e080 Merge branch 1.8.9-dev into 1.9.4-dev
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
8fad02c Merge branch 1.8-dev into 1.8.9-dev
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
1c888aa Add minVersion to mixin configs and bump bundled mixin version
10ce71e Fix mapwriter crash when opening replay for <MC1.12 (fixes#96)
5fb1cf3 Fix half-despawned player entities (see #93) when the entity is moved greater distances
adfe6a2 Fix NPE when spectated non-player entity despawns (fixes#94)
b27af27 Fix player entities being half-despawned after jumping in time (fixes#93)
@@ -4,46 +4,38 @@ A Minecraft mod to record game sessions and replay them afterwards from any pers
## Building
Make sure your sub-projects are up-to-date: `git submodule update --init --recursive`
For each branch you visit the first time, running `./gradlew setupDecompWorkspace` is necessary.
This will also be necessary if the `replaymod_at.cfg` file has been changed (getting errors about code that is trying
to access private fields is a good indication that this has happened).
For compiling 1.7.10, you must run `./gradlew :jGui:1.7.10:setupDecompWorkspace :1.7.10:setupDecompWorkspace` once after the initial clone. This may take quite some time.
### No IDE
You can build the mod by running `./gradlew :build`. You can then find the final jar files in `build/libs/`.
You can build the mod by running `./gradlew build` (or just `./gradlew bundleJar`). You can then find the final jar files in `versions/$MCVERSION/build/libs/`.
You can also build single versions by running `./gradlew :1.8:build` (or just `./gradlew :1.8:bundleJar`) (builds the MC 1.8 version).
### IntelliJ
For the initial setup run `./gradlew preshadowJar idea genIntellijRuns`.
You also need to enable the Mixin annotation processor:
1. Go to File -> Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors
2. Tick "Enable annotation processing"
3. Add a new entry to the "Annotation Processor options"
4. Set the name to "reobfSrgFile" and the value to "$path/build/mcp-srg.srg" where you replace $path with the full
path to the folder containing the gradlew file
Whenever you switch to another branch, you can either just run `./gradlew preshadowJar idea` or instead run
`./gradlew preshadowJar copySrg` and then refresh the gradle project from within IntelliJ.
Ensure you have at least IDEA 2020.1.
Build the mod via Gradle as explained above at least once (`./gradlew compileJava` should be sufficient). This will ensure that the sources for all MC versions are generated.
Then import the Gradle project from within IDEA: File -> Open -> build.gradle -> Open as Project
Finally configure IDEA to build everything by itself instead of delegating it to Gradle (cause that is slow): File -> Settings -> Build, Execution, Deployment -> Build Tools -> Gradle -> Build and run using: IntelliJ IDEA
### Eclipse
## Development
### Branches
New features are developed on the `1.8` branch and merged upwards for release. Larger features are developed on their
own branch that is based on `1.8` and then merged back once it's finished.
Loosely based on [this branching model](http://nvie.com/posts/a-successful-git-branching-model/) with `stable` instead of `master`.
Features or bug fixes that apply only to a specific Minecraft version are fixed on the branch corresponding to that
version and reverted when merging upwards.
Both subprojects follow a similar branching model.
The user documentation (`docs` folder) is only committed to on the current development branch. Any changes committed on
a branch for a more recent Minecraft version are not kept up to date on the website and should only be
of importance once support for the previous Minecraft version is dropped.
TL;DR:
Main development happens on the `develop` branch, snapshots are built from this branch.
The `stable` branch contains the most recent release.
The `master` branch is solely to be used for the `version.json` file that contains a list of all versions
used by the clients to check for updates of this mod.
### The Preprocessor
To support multiple Minecraft versions with the ReplayMod, a [JCP](https://github.com/raydac/java-comment-preprocessor)-inspired preprocessor is used.
It has by now acquired a lot more sophisticated features to make it as noninvasive as possible.
Please read the [preprocessor's README](https://github.com/ReplayMod/preprocessor/blob/master/README.md) to understand how it works.
### Versioning
The ReplayMod uses the versioning scheme outlined [here](http://mcforge.readthedocs.io/en/latest/conventions/versioning/)
The ReplayMod uses the versioning scheme outlined [here](https://docs.minecraftforge.net/en/1.12.x/conventions/versioning/)
with three changes:
- No `MAJORAPI`, the ReplayMod does not provide any external API
- "Updating to a new Minecraft version" should not increment `MAJORMOD`, we maintain one version of the ReplayMod
@@ -52,19 +44,18 @@ keep the version name the same for all of them (with the exception of `MCVERSION
"Multiple Minecraft Version" section does not apply.
- For pre-releases the shorter `-bX` is used instead of `-betaX`
When a new version is (pre-)release, a new annotated tag should be added with the name of the version and the
When a new version is (pre-)release, a new commit modifying the `version.txt` file should be added and the
`versions.json` file in the `master` branch should be updated. To simplify this process the gradle task `doRelease` can
be used: `./gradlew -PreleaseVersion=1.8-2.0.0-rc1 doRelease`. It will create the tag and update the version.json
be used: `./gradlew -PreleaseVersion=2.0.0-rc1 doRelease`. It will create the commit and update the version.json
accordingly.
Care should be taken that the updated `version.json` is not pushed before a jar file is available on the
download page (or Jenkins) as it will inform the users of the update.
### Bugs
Bugs in the mod are tracked via [Bugzilla](https://bugs.replaymod.com/).
GitHub should only be used for issues that are generally not likely to affect any end users.
GitHub should generally be used to report bugs.
Bug numbers in commits such as `(fixes #42)` refer to Bugzilla unless noted otherwise.
In the past, bugs were tracked via [Bugzilla](https://bugs.replaymod.com/), so bug numbers in commits prior to 2020 such as `(fixes #42)` generally referred to Bugzilla unless noted otherwise.
## License
The ReplayMod is provided under the terms of the GNU General Public License Version 3 or (at your option) any later version.
The **ReplayMod** requires **Minecraft Forge** to be installed.
### Minecraft 1.14 and above
The **ReplayMod** for Minecraft 1.14 and above requires **Fabric** to be installed.
Depending on your **Replay Mod** version we recommend the following **Forge** versions:
You can find Fabric and the installation instructions [here](https://fabricmc.net/use/).
- ReplayMod 2.0.0 or later for Minecraft 1.11: Forge [1.11-13.19.1.2189](https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.11.html)
- Replay Mod 2.0.0 or later for Minecraft 1.10.2: Forge [1.10.2-12.18.2.2099](https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.10.2.html)
- Replay Mod 2.0.0 or later for Minecraft 1.9.4: Forge [1.9.4-12.17.0.1976](https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.9.4.html)
- Replay Mod 2.0.0 or later for Minecraft 1.8: Forge [1.8-11.14.4.1563](https://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.8.html)
- Replay Mod 1.0.8 or older for Minecraft 1.8: Forge [1.8-11.14.3.1450](http://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.8.html)
After installing Fabric, simply put the downloaded ReplayMod .jar file into the `/mods` folder of your Minecraft directory.
Other Forge Versions might, but don't necessarily work.
### Minecraft 1.12.2 and below
For Minecraft 1.12.2 and below it requires **Minecraft Forge** to be installed.
If you don't know how to install Forge, follow [this tutorial](https://www.youtube.com/watch?v=4i7-RystzC4).
@@ -19,63 +17,44 @@ After installing Forge, simply put the downloaded `ReplayMod.jar` file in the `/
> **Note:** The **Replay Mod** is entirely client side and can not be installed on the servers you play on.
## Installing FFmpeg [ffmpeg]
To use the**Replay Mod**'s [Rendering Feature](#replaying-render), you need to have FFmpeg installed.
To render your creations with **Replay Mod** you will need to have FFmpeg installed.
### Windows [windows]
Download the latest **FFmpeg Static Build** for your architecture from <http://ffmpeg.zeranoe.com/builds/>.
Then, extract the downloaded `.7z` file in the folder you want to install FFmpeg in.
Download the latest FFmpeg release from https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip.
Next, download this **Batch Script** to quickly install FFmpeg: <https://replaymod.com/files/ffmpeg-path-installer.bat>
Extract the downloaded .zip file into your `.minecraft` folder.
> **Note:** If your browser warns you about the download, dismiss the message. It's a simple Batch Script which won't damage your computer.
Historically the exact location inside the `.minecraft` folder was important, this is no longer the case.
It is sufficient for the `ffmpeg.exe` to be anywhere inside your `.minecraft` folder.
Put the downloaded script into the folder where you extracted FFmpeg and run itt by double-clicking it.
If you see a success message in the console, you've sucessfully installed **FFmpeg**!
**Notes for alternative launchers**
- Twitch launcher by default installs Minecraft instances in C:\\Users\\*username*\\Twitch\\Minecraft\\Instances\\*instancename*\\
- GD Launcher by default installs Minecraft instances in C:\\Users\\*username*\\AppData\\Roaming\\gdlauncher_next\\instances\\*instancename*\\
- MultiMC by default installs Minecraft instances in C:\\Program Files (x86)\\MultiMC\\instances\\*Instancename*\\.minecraft\\
Alternatively, starting with ReplayMod 2.0.0-b5, you can also extract the downloaded `.7z` file into a `ffmpeg` folder
(you have to create it, it doesn't exist by default) in your `.minecraft` folder. No need to run any **Batch Script**.
The FFmpeg executable should end up at `.minecraft/ffmpeg/bin/ffmpeg.exe`.
For these launchers, make sure FFmpeg exists inside the corresponding folder.
### Mac OSX [mac]
On OSX, you can install **FFmpeg** with **[Homebrew](http://brew.sh/)** using `brew install ffmpeg`.
Alternatively, you can download the latest static build from <https://ffmpeg.org/> and copy the ffmpeg executable to `/usr/local/bin`.
Alternatively, you can download the latest static build from <https://ffmpeg.org/> and copy the FFmpeg executable to `/usr/local/bin`.
### Linux [linux]
On Linux, you can install **FFmpeg** using your system's package manager, for example using `apt install ffmpeg`.
If in doubt, consult the documentation of your distribution.
## Compatibility with other Mods [compatibility]
### General information [general]
In General, the Replay Mod _should_ be compatible with most Forge Mods.
is no longer compatible with Minecraft Forge starting with 1.9.4. As such it is not compatible with the Replay Mod either.
Please use [Optifine](https://optifine.net/) instead.
### Custom Main Menu [custom-main-menu]
The [Custom Main Menu](https://mods.curse.com/mc-mods/minecraft/226406-custom-main-menu) mod is often used in mod packs to customize their Main Menu with a button layout fitting the background image, links to their website / bug tracker and similar.
If you are familiar with it, the button ids for the Replay Mod are: **17890234** (text: `replaymod.gui.replayviewer`), **17890237** (text: `replaymod.gui.replayeditor`) and **17890236** (text: `replaymod.gui.replaycenter`)
Due to the nature of this Custom Main Menu mod, buttons added to the Main Menu by 3rd party mods like the **Replay Mod** will not show up by default.
Thus, to access the Replay Viewer/Editor/Center, you need to manually configure the position for those buttons.
To do so, you need to modify the Custom Main Menu configuration file.
Usually, you can find it at `.minecraft/config/CustomMainMenu/mainmenu.json` (if you're using a mod pack launcher, it normally has its own .minecraft folder).
For an explanation of this config file, have a look at Custom Main Menu's page.
You can find a list of already modified config files [here](https://gist.github.com/Johni0702/3f3fab81dbf7ada83d045d9fe8f345aa).
## Troubleshooting [troubleshooting]
If you need help installing the **Replay Mod** or **FFmpeg**, please read [this forum thread](https://www.replaymod.com/forum/thread/220)
by [bela333](https://www.replaymod.com/user/bela333) - it covers most of the problems that users encountered so far.
## Settings [settings]
To access the **Replay Mod Settings** from the Main Menu click the **"Mods"** button, select the **Replay Mod** from the list and
the click the **"Config"** button.
To access the **Replay Mod Settings** from the Main Menu click the **"Replay Viewer"** button and click the **Settings** button.
While playing, you can click the 'Mods' button in the Pause screen to reach **Replay Mod Settings** if you use Minecraft 1.12.2 and below, or have the mod _Mod Menu_ installed.
When in a Replay, you can either bind a hotkey to the **Replay Mod Settings** in Minecraft's Control settings
or use the hotkey GUI by clicking on the arrow button in the lower left corner.
or use the hotkey GUI by clicking on the hamburger button in the lower left corner.
## Accounts [accounts]
In previous versions of ReplayMod we used accounts to deliver videos to the **Replay Center**. This has since been discontinued and with that, so have the accounts.
Instead of the forum, you can join our [Discord server](https://discord.gg/5GR7RSb) to get support and answers.
# Recording [recording]

@@ -143,15 +122,13 @@ The minimum Speed value is **0.1 times** the normal Minecraft Tick Speed, and th
To the right of the Speed Slider, there is the **Replay Timeline**.
On the Replay Timeline, you see a yellow cursor indicating your current position in the Replay.
By clicking somewhere on this Timeline, you will travel in time towards the specified point in time.
Please note that it takes longer to do larger steps in time or to jump backwards in time.
Please note that it takes longer to do larger steps in time or to jump backwards in time (see also [Quick Mode](#replaying-quickmode)).
## Camera Paths [paths]
### Introduction [intro]
While in a Replay, you can create controlled **Camera Movements** using the Mods's **Keyframe System**.
Those Camera Paths can be rendered to a video later (see [Rendering](#replaying-render)).
Camera Paths are inspired by the [PixelCam Mod](http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2327429-pixelcam-camera-studio-for-minecraft-1-8) which is based on the Camera Studio Mod.
The **Replay Mod Keyframe System** is similar to many Video Editing Software's Keyframe Systems.
If you're new to Keyframe Systems, try reading [this Wikipedia article](https://en.wikipedia.org/wiki/Key_frame).
@@ -170,6 +147,8 @@ If two Keyframes are 5 seconds apart, the Camera Path will take 5 seconds to int
You can drag Keyframes on the **Keyframe Timeline** by left-clicking them, holding the mouse button and moving your mouse.
> **Hint:** Made a mistake? You can use `Ctrl+Z` to undo your changes to the keyframe timeline. Changed you mind? Press `Ctrl+Y` (or `Ctrl+Shift+Z`) to redo them.
### Position Keyframes [place]
The basic components of a Camera Path are **Position Keyframes**.
A Position Keyframe stores a **Camera Position** (x, y, z, yaw, pitch, roll).
@@ -200,9 +179,6 @@ If you wish to disable smooth interpolation and want to make the Path follow str
You can easily toggle between **Linear** and **Cubic Interpolation** using the `O` key.
#### Path Preview [preview]

While the **Path Preview** is enabled, this camera symbol is displayed in the lower right corner of the screen.

A normal **Path Preview**
@@ -278,60 +254,6 @@ You can change a Preset's name, select it from the list and click the **"Rename"
To load a Keyframe Preset, select a Preset from the list and click the **"Load"** button.
Using the **"Remove"** button, you can permanently delete a Keyframe Preset from the **Keyframe Repository**.
## Custom Objects [objects]
> Custom Objects are not available in the 2.0.0 versions. They are expected to return eventually.
[YouTube](_Xdpg828fbE)
### Introduction [introduction]
**Custom Objects** are mainly meant for **video creators**. They allow you to add any image into the Replay World and animate its Position, Opacity and much more.
Instead of using [Motion Tracking](https://en.wikipedia.org/wiki/Match_moving) to add text or pictures to a video, you can directly add these to the rendered file.
### Adding Assets [assets]

The **Asset Manager** with an example Asset
In order to create **Custom Objects**, you first have to add **Assets** to your Replay File.
Therefore, open the **Asset Manager** using the `G` key.
In the **Asset Manager**, you can add **Image Files (.png, .jpg and more)**, so-called **Assets**, to the Replay.
When clicking the **"Add"** button, a File Chooser will show up. Select the image file you want to use.
You can give the Asset a custom name using the Text Input Field in the top right corner.
All of the Assets you added can be used by **Custom Objects**.
### Creating Custom Objects [creating]

The **Object Manager** with some **Animation Keyframes**
Using the `F` key, you can open the **Object Manager**. Initially there won't be any Objects in the **Object List**, but you can simply add an Object using the **"Add"** button.
After doing so, you can name the newly created **Custom Object** using the Text Field in the upper right corner.
To define which **Asset File** (i.e. image) the **Custom Object** should use, select the desired **Asset** from the dropdown beneath the Name Input.
If you leave the **Object Manager**, you should see the image in the World somwhere near your position.
### Animating Custom Objects [animating]

An animated **Custom Image Object**.
Of course, you don't want the image to stay at that position.
herefore, open the **Object Manager** again and select the **Custom Object** you want to modify.
On the lower half of the screen you will see mutliple **Input Fields**, using which you can modify various settings
(so-called **Transformations**), for example the Object's **Position**, **Scale**, **Orientation** and **Opacity**.
When editing these values, you'll notice that on the TImeline to the right, Keyframes appear.
You can set and remove Keyframes for specific settings using its "Add Keyframe" button on the very left of the screen.
The **Object Manager's Keyframe System** is very similar to the **Position Keyframe** and **Time Keyframe** System.
During a **Camera Path**, the **Custom Objects** will interpolate their **Transformation Values** like **Position Keyframes** are interpolated.
While outside the **Object Manager** you can preview the Objects' position by moving the cursor on the **Keyframe Timeline** - the Objects will interpolate to the position they'll be at that timestamp during the **Camera Path**.
Once you got the hang of it, you'll be able to quickly animate **Custom Objects**.
## Rendering [render]
With the **Replay Mod**, you can render **Camera Paths** to videos **without** using a screen recording tool like Fraps.
To get started, first [set up your Camera Path](#replaying-paths) as described in the previous chapters.
@@ -436,7 +358,14 @@ There are **7 Encoding Presets** you can choose from:
While these video files are of perfect quality, most **non-FFmpeg-based video players and video editing software** (e.g. QuickTime Player, Sony Vegas and Adobe Premiere) can't play these videos. Therefore, you should instead use the **MP4 - High Quality** preset in most cases.
- **PNG Sequence**
Exports the sequence as individual frames in the **PNG Format**.
**Warning:** This can create a huge amount of files, so make sure to save them in a separate folder.
The images are of perfect quality.
Depth map images are 32-bit float encoded in the 8-bit components in BGRA order and will need some kind of post-processing to be useful in most editors.
- **OpenEXR Sequence** (Minecraft 1.14 and above)
Exports the sequence as individual frames in the **OpenEXR Format**.
The images are of perfect quality and may contain
additional image layers beyond the visible one (e.g. [depth](#replaying-render-advanced-depth-map)).
As such, this format is a good choice if you have plenty of disk space to spare and want to perform additional editing
on the video in a third-party video editor.
### Advanced Settings [advanced]

@@ -463,6 +392,21 @@ Using a **Video Editing Software** like **Adobe After Effects** or **Sony Vegas*
> **Note:** For best results, you should **disable clouds** before rendering, as they are transparent.
#### Depth Map [depth-map]

"Suzanne" model added into a scene using Blender
This setting causes depth information to be recorded and included in video formats which support it
(currently only [OpenEXR](#replaying-render-settings-quality)).
Using a video editor which supports it (e.g. [Blender](https://www.blender.org/)), you can then for example (among many
other effects) add arbitrary geometry onto your rendered video in such a way that foreground objects in the
video will still occlude background geometry as if it actually was part of the world.
> **Note:** For best results, avoid semi-transparent blocks in front of your geometry, as they cannot be accurately represented in the depth map.
> **Note:** Anti-aliasing is not supported when exporting depth. Instead simply render and edit your video at a higher resolution and scale it down at the very end.
### Command Line Settings [commandline]

The **Command Line Render Settings**
@@ -475,7 +419,7 @@ The **Replay Mod** runs [FFmpeg](http://ffmpeg.org/) via the **Command Line** to
You can customize both the **executed Command** and the **Command Line Arguments** in the **Command Line Settings** part of the **Render Settings Screen**.
#### Custom Command [command]
If you leave the left input field blank, `ffmpeg` will be used as **command**. If you haven't set your **PATH variable** to link to your FFmpeg distribution, simply enter the full path to your FFmpeg executable (e.g. `C:/ffmpeg/ffmpeg.exe` or `/usr/local/bin/ffmpeg`).
If you leave the left input field blank, `ffmpeg` will be used as **command**. If you haven't set your **PATH variable** to link to your FFmpeg distribution, simply enter the full path to your FFmpeg executable (e.g. `C:\ffmpeg\ffmpeg.exe` or `/usr/local/bin/ffmpeg`).
#### Command Line Arguments [arguments]
In the right input field, you can input custom **Command Line Arguments** to be used in the console.
@@ -510,29 +454,6 @@ To use **High Performance Rendering**, hold down the `Ctrl` key (`Cmd` key on M
but only after one rendered seconds (e.g. every 60 frames when rendering with 60fps)
- Resizing the Minecraft Window does not update the Rendering Gui
### Troubleshooting [troubleshooting]
> If you have trouble with rendering, please first consult the Documentation before asking for help in the Forums.
#### No FFmpeg installation found [ffmpeg]

The error screen that is displayed when no FFmpeg installation could be found
If the **Replay Mod** tells you to install FFmpeg even though you already have, you have to manually tell the **Replay Mod** where your FFmpeg executable is located.
First, get the full path to your `ffmpeg.exe` (on Windows) or `ffmpeg` executable (on Mac/Linux).
On Windows, this path might look like `C:/ffmpeg/ffmpeg.exe`.
Then, open the **"Command Line Settings" Tab** in the Render Settings and paste this path into the **left input field** and retry rendering.
#### Crash while rendering [crash]
If Minecraft crashes after a few frames of rendering, it most likely means the **FFmpeg** didn't like the **Command Line Arguments** you passed.
If you customized the Command Line Arguments manually, re-check them - it's probably your own fault.
> **Hint:** In your .minecraft folder, you'll find a file called `export.log` which contains information about FFmpeg's rendering process.
If you did **not** customize the **Command Line Arguments**, you might have entered some insanely high (or low) values e.g. for Bitrate or Video Resolution. Try again with other, more reasonable values.
## Ambient Lighting [lighting]

The same setting, onace with **Ambient Lighting** enabled, once with **Ambient Lighting** disabled
@@ -544,6 +465,14 @@ If you have a Replay in a dark setting (for example at nighttime, or in a cave)
This works as a replacement for the **Night Vision Potion Effect**, without the side effect of a weird sky color.
## Quick Mode [quickmode]

In **Quick Mode**, this clock symbol is displayed in the lower right corner of the screen.
When you first enable **Quick Mode** in a replay, an internal reference of certain entity and block properties is stored for quick access, allowing for faster navigation in the **Replay Timeline**.
As a side effect, certain features like particles and second skin layers will not be rendered in the preview.
By default, **Quick Mode** is toggled with `Q`.
## Player Overview [overview]

The **Player Overview** Screen
@@ -567,11 +496,9 @@ The **Default Thumbnail** which is used if no Thumbnail was created
While in a Replay, you can use the `N` key to create a **Thumbnail** of the current Replay.
A **Thumbnail** is a Screenshot which should give the viewer a good impression of your Replay's content.
**Thumbnails**are important when uploading a Replay to the**Replay Center**,
as other users are much more likely to download your Replay if they can see a preview of it.
They also help keeping your **Replay Viewer** clear and structured.
**Thumbnails**help keeping your**Replay Viewer** clear and structured.
If no **Thumbnail** is set for a Replay, the **Default Thumbnail** will be displayed in the **Replay Viewer** and in the **Replay Center**.
If no **Thumbnail** is set for a Replay, the **Default Thumbnail** will be displayed in the **Replay Viewer**.
## Event Markers [markers]

@@ -594,84 +521,8 @@ This way, it's even simpler to add structure to your Replays.
You can **delete an Event Marker** by clicking it once to select it and then pressing the `DELETE` key.
# Replay Center [center]
The **Replay Center** is where you can **share** your **Minecraft Moments** with others and discover awesome **Replays by other Users**.
To be able to use the **Replay Center**, you need an **account on ReplayMod.com**.
## Authentication [auth]

The **Login Screen** which is displayed upon startup

The **Register Screen**
When starting Minecraft with the **Replay Mod** installed, you will be asked to login to **ReplayMod.com**.
If you don't want to use the **Replay Center**, you can click the **"Skip" Button** to continue without logging in.
If you want to browse other users' **Replays** and **share your own Replays** however, you need to **Register an account**.
> **Note:** By registering an Account on **ReplayMod.com**, you agree to the Website's [Terms of Service](https://www.replaymod.com/legal/terms)
Please note that you can only create **one ReplayMod.com Account per Minecraft Account**, so choose your username wisely.
Once you've registered, you're automatically going to be logged in. The Mod **remembers your login** until you manually log out from the **Replay Center**, so it won't ask you upon every startup if you logged in once.
## Replay Files [files]

The **Replay Center** in the Mod
Once you've logged in, you can use the **"Replay Center" Button** in the Main Menu to access the **Replay Center**.
In the upper half of the screen, there are **5 Buttons** for **5 Tabs** of the **Replay Center**:
- **Recent**
Shows the most recently uploaded Replays in the **Replay Center**
- **Best**
Shows the Replays with the **best rating and most downloads**
- **Downloaded**
Shows all of the Replays you've downloaded locally
- **Favorited**
Shows all of the Replays you favorited
- **Search**
Allows you to search for specific Replays
When you've found an insteresting looking Replay, you can download it using the **"Download" Button** in the lower left corner.
After downloading, you'll automatically join the Replay.
After you've downloaded a Replay, you can rate and favorite it in the **Replay Center** using the respective buttons.
> You are encouraged to rate Replays after you downloaded them to help promoting the best Replays.
## Upload Replays [upload]

The **Replay Upload Screen**
You can share your own **Replay Files** with other users in the **Replay Center**.
Therefore, click the **"Upload" Button** in the **Replay Viewer** after selecting a Replay.
In the **Replay Upload Screen** there are **6 input fields**:
- **Replay Name**
The Replay's Name in the Replay Center
- **Replay Description**
A description of what happens in the Replay. Try to give the user a good impression why your Replay is worth downloading.
- **Category**
The Replay's Category, one of the following: **Survival**, **Build**, **Minigame**, **Miscellaneous**. If none of the other categories fit, use **Miscellaneous**.
- **Tags**
One or more tags that fit your replay, spearated by comma. **Example tags:** pvp,battle,redstone,creative
- **Hide Server IP**
If you've recorded a Replay on a private Server, you can remove the Server IP by checking the respective checkbox.
- **Thumbnail**
While you can't directly edit the Thumbnail when uploading, it is highly recommended that
you [create a Thumbnail](#replaying-thumbnail) before sharing your Replay.
Replays without a Thumbnail are much less likely to be downloaded by other users.
When uploading a Replay File, make sure to follow the [Replay Center Rules](https://www.replaymod.com/rules).
# Frequently Asked Questions [faq]
### Do I need a ReplayMod.com Account to use the mod?
You only need a ReplayMod.com Account to access the [Replay Center](#center).
All of the other features are also available offline.
### For how long can I record?
Theoretically, a Replay File can be up to **24 days, 20 hours, 30 minutes and 23 seconds** long - which is a timespan you'll probably never reach.
@@ -694,3 +545,113 @@ A Replay in which you travelled around and discovered a lot of terrain is signif
An average Replay File of **10 Minutes duration** usually is between **2MB and 10MB large**.
Replays recorded on **Minigame Servers** with lots of particle effects and world changes might be larger.
# Troubleshooting [troubleshooting]
> If you have trouble with rendering, please first consult the Documentation before asking for help in the Discord.
## No FFmpeg installation found [ffmpeg]

The error screen that is displayed when no FFmpeg installation could be found
If you have not installed FFmpeg, please follow the steps provided [here](#installing-ffmpeg)
If already have installed FFmpeg, you have to manually tell the **Replay Mod** where your FFmpeg executable is located.
First, get the full path to your `ffmpeg.exe` (on Windows) or `ffmpeg` executable (on Mac/Linux).
On Windows, this path might look like `C:\ffmpeg\ffmpeg.exe`.
Then, open the **"Command Line Settings" Section** in the Render Settings and paste this path into the **left input field** and retry rendering.
## Crash while rendering [crash]
If Minecraft crashes after a few frames of rendering, it most likely means the **FFmpeg** didn't like the **Command Line Arguments** you passed.
If you customized the Command Line Arguments manually, re-check them - it's probably your own fault.
> **Hint:** In your .minecraft folder, you'll find a file called `export.log` which contains information about FFmpeg's rendering process.
- If you did **not** customize the **Command Line Arguments**, you might have entered some insanely high (or low) values e.g. for Bitrate or Video Resolution. Try again with other, more reasonable values.
- Make sure the camera doesn't move below Y=0 or above Y=255
## Unsupported Launchers [launchers]
_Future Client_ is not compatible with the Mixin required by ReplayMod.
_Lunar Client_ does not support ReplayMod.
_Badlion Client_ offers a different ReplayMod that is not the same as this one.
## Compatibility with other Mods [compatibility]
### General information [general]
In General, the Replay Mod _should_ be compatible with most Forge and Fabric Mods.
### Shaders Mod [shaders]
_Karyonix' Shaders Mod_ is no longer compatible with Minecraft Forge starting with 1.9.4. As such it is not compatible with the Replay Mod either.
Below Minecraft 1.16 you can try _Optifine_ instead. Note however, that official support has ended and many versions break ReplayMod.
On Minecraft 1.16.5 and up you can use _Iris_, which is fully supported. For the time being, you will have to use it with the custom _Sodium_ provided on our download page. The fix it includes is pending for the official version.
### Custom Main Menu [custom-main-menu]
The _Custom Main Menu_ mod is often used in mod packs to customize their Main Menu with a button layout fitting the background image, links to their website / bug tracker and similar.
If you are familiar with it, the button id for the Replay Mod is: **17890234** (text: `replaymod.gui.replayviewer`).
Due to the nature of this Custom Main Menu mod, buttons added to the Main Menu by 3rd party mods like the **Replay Mod** will not show up by default.
Thus, to access the Replay Viewer/Editor/Center, you need to manually configure the position for those buttons.
To do so, you need to modify the Custom Main Menu configuration file.
Usually, you can find it at `.minecraft/config/CustomMainMenu/mainmenu.json` (if you're using a mod pack launcher, it normally has its own .minecraft folder).
For an explanation of this config file, have a look at Custom Main Menu's page.
You can find a list of already modified config files [here](https://gist.github.com/Johni0702/3f3fab81dbf7ada83d045d9fe8f345aa).
### Tickrate Changer [tickrate-changer]
The _Tickrate Changer_ mod may cause minecraft to freeze when you try to use the Replay Viewer UI.
### LabyMod [labymod]
_LabyMod_ v3.7.x has been reported to be compatible with ReplayMod and other Forge mods.
Lower versions are not compatible.
### OldAnimationsMod [oldanimationsmod]
In case your Minecraft crashes when you are using both ReplayMod and _OldAnimationsMod_, try removing OldAnimationsMod.
### Orange's 1.7 Animations [17animations]
If you use ReplayMod with shaders and _1.7 Animations_ you may see floating water and glass. Remove 1.7 Animations to resolve this.
### Sk1er Club: Patcher [patcher]
We have seen reports of crashes that were related to _Patcher_; in case of crashes try removing Patcher.
### Baritone [baritone]
The _Baritone_ mod can cause a crash when you're trying to load a replay. If you experience such problems, try running without Baritone.
### RandomPatches [randompatches]
Minecraft may crash if you try to use _RandomPatches_ together with ReplayMod. Try removing RandomPatches if Minecraft crashes on startup.
### Sodium [sodium]
ReplayMod can record when _Sodium_ is installed, but currently lacks the FREX Flawless Frames API to render. A modified build of _Sodium_, that supports this API, is available from the ReplayMod downloads, by clicking the `Click to show compatible Sodium versions` button.
### Resource Loader [resourceloader]
The _Resource Loader_ mod is not compatible with ReplayMod.
### LiteLoader [liteloader]

The MultiMC interface to place ReplayMod above LiteLoader.

The properties for the new *Empty*.
_LiteLoader_ is known to cause issues due to the mixin version it contains.
You can use MultiMC to workaround this problem.
> The MultiMC `Edit` function requires that your computer has a default editor for json files associated.
1: Create your instance then edit the instance
2: Click `Install Forge`
3: Click `Install LiteLoader`
4: Click `Add Empty`; use `ReplayMod` as name and `com.replaymod` as uid
5: Select the new *ReplayMod* and click `Edit`
6: Replace the contents with one of the below snippets
7: Save and close the text editor
8: Move *ReplayMod* up until it is **above***LiteLoader*
9: Remove the ReplayMod jar from the mods folder if you installed it previously.
* Orange seems to have copied vast parts of the RendererLivingEntity into their ArmorAnimation class which cancels the RenderLivingEvent.Pre and calls its own code instead.
* This breaks our mixin which assures that, even though the camera is in spectator mode, it cannot see invisible entities.
*
* To fix this issue, we simply cancel the RenderLivingEvent.Pre before it gets to ArmorAnimation if the entity is invisible.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.