Replay Mod (Fabric & Forge)

Replay Mod (Fabric & Forge)

787k Downloads

API for developers to play cutscenes in their mods?

Opened this issue ยท 7 comments

commented
commented

Please elaborate.

commented

Developers create camera paths in game. Then press export as replay file. They can then, using the library, import the replay file (from a resource pack/path) and play it.

The chunks from the replay file will be loaded temporarily and any players/entities loaded aswell.

Then the developer can play, pause, rewind, speed up, slow down etc. via code.

commented

See this: https://github.com/raphydaphy/CutsceneAPI

An example, but its for 1.14, and very outdated.

commented

From the game's PoV, replays appear to be a (more or less) regular server. And just like you cannot be connected to two servers at the same time, you cannot play a replay while connected to another server or single player. That seems like a deal breaker for what you want or am I missing something?

commented

Personally, i'm suggesting this for a massive single player mod i've been working on. It relies heavily on story. Even if it requires the player to leave the world silently then play the replay, then re-join seamlessy, it would work.

If the case is that the player needs to leave the world to play the cutscene, the loading scene can easily be replaced with mixins, to images etc.

commented

Hm, I don't think that's useful enough in general to warrant creating an API for it.
Seems easier and much more flexible to just update that other project.

If you want to play with it nonetheless, here's a piece of code which loads a replay from a file, plays it until there's a world, then does some processing (here you could continue playing the replay and move the player as required for your cutscene) and then, some time later, closes the replay (before recursively loading the next one):

LOGGER.info("Opening replay {} for {} render jobs", next.getKey(), next.getValue().size());
ReplayHandler replayHandler;
ReplayFile replayFile = null;
try {
replayFile = mod.getCore().openReplay(next.getKey().toPath());
replayHandler = mod.startReplay(replayFile, true, false);
} catch (IOException e) {
Utils.error(LOGGER, container, CrashReport.create(e, "Opening replay"), () -> {});
container.display(); // Re-show the queue popup and the new error popup
IOUtils.closeQuietly(replayFile);
return;
}
if (replayHandler == null) {
LOGGER.warn("Replay failed to open (missing mods?), skipping..");
IOUtils.closeQuietly(replayFile);
processMultipleReplays(container, mod, queue, done);
return;
}
ReplaySender replaySender = replayHandler.getReplaySender();
MinecraftClient mc = mod.getCore().getMinecraft();
int jumpTo = 1000;
while (mc.world == null && jumpTo < replayHandler.getReplayDuration()) {
replaySender.sendPacketsTill(jumpTo);
jumpTo += 1000;
}
if (mc.world == null) {
LOGGER.warn("Replay failed to load world (corrupted?), skipping..");
IOUtils.closeQuietly(replayFile);
processMultipleReplays(container, mod, queue, done);
return;
}
processQueue(container, replayHandler, next.getValue(), () -> {
try {
replayHandler.endReplay();
} catch (IOException e) {
Utils.error(LOGGER, container, CrashReport.create(e, "Closing replay"), () -> {});
container.display(); // Re-show the queue popup and the new error popup
return;
}

commented

Awesome thanks ๐Ÿ‘