HomeJavaModsConditionalVideos
ConditionalVideos
ModsJava

ConditionalVideos

by MateoF024 · on Modrinth

Plays custom videos when specific in-game events are detected. It is designed for curated gameplay experiences such as servers, story maps, quest packs…

⬇ Download on Modrinth

🎬 ConditionalVideos

Server-aware cinematic triggers for Minecraft. Configure conditions once and let clients play synced videos — local files, URLs, or full playlists — exactly when it matters.

Modrinth Downloads CurseForge Downloads

Fabric Forge 1.20.1 NeoForge Environment

Wiki Issues


✨ Overview

ConditionalVideos plays custom videos when specific in-game events are detected — first joins, deaths, kills, advancements, item milestones, scoreboard thresholds, and more.

It runs on both client and dedicated server: the server detects conditions and tells the right client what to play, while the client handles the actual playback. This makes it a good fit for servers, story maps, quest packs, and roleplay setups where cinematic feedback improves immersion.

Highlights


🧩 Compatibility & Requirements

Minecraft Loaders Java
1.20.1 Fabric, Forge 17+
1.21.1 Fabric, NeoForge 21+
1.21.11 Fabric, NeoForge 21+
26.1.2 Fabric, NeoForge 25+
26.2 Fabric, NeoForge 25+

On 26.2 the game can run with either renderer. Videos play on both, but support for the Vulkan renderer is experimental — Minecraft ships it as an opt-in preview, so OpenGL remains the safest choice if you hit trouble.

Required (client side):

Config files:

In multiplayer the dedicated server owns the config, ships any local video files to clients automatically (cached and reused on reconnect), and URLs are streamed directly by each client. Treat conditionalvideos-server.json as the source of truth for server content.


🎯 Supported Conditions

Each condition is configured with a playlist. Simple conditions use a single config key; keyed conditions are a map of id → condition.

Simple (single key):

Keyed (map of id → condition):

Scoreboard comparators

Each scoreboard entry compares a player's score against a value using a comparator:

comparator Fires when
equal score == value
less score < value
greater score > value
lessOrEqual score <= value
greaterOrEqual score >= value (default)

It is edge-triggered: a satisfied comparison fires once and only re-arms after it turns false and crosses back to true. Because scores persist with the world, a comparison already satisfied before logout does not re-fire on rejoin.


🗂️ Configuring conditionalvideos.json

Each condition entry holds a playlist under videos: [...] plus a few shared flags. Each item in videos is a VideoEntry describing one clip and its overlay / skip / loop / transition options. Only firstJoin ships preconfigured; every other condition starts as an empty {} until you add videos.

Shared condition fields

Property Type Required Description
repeatableInSameSession boolean Yes If false, the condition can trigger once per session. If true, it can trigger repeatedly.
playlistLoop boolean No When true, the playlist restarts from the first entry after the last finishes. Default false.
videos VideoEntry[] Yes One or more entries played in order. Length 1 behaves like a single-video setup.

scoreboard entries add two fields at the condition level: value (int, required — the threshold) and comparator (string, optional — default greaterOrEqual).

VideoEntry fields

Property Type Required Description
source string Yes A path to a local video file (relative to the game directory or absolute) or a URL (http://, https://, YouTube link).
skippable boolean No If true, the user can skip playback. Default true. Forced to true when videoLoop = true.
videoLoop boolean No If true, the entry loops seamlessly until skipped. Default false. Requires skippable = true.
enableBackground boolean No Draws a solid-color full-screen background behind the video. Default true.
colorBackground string No Hex color in #RRGGBB or #AARRGGBB. Default #000000.
videoTitle string No Optional title overlay. Supports legacy format codes (&6, &l, &r, …).
videoTitlePosition string No topLeft, topRight, bottomLeft, bottomRight. Default bottomLeft.
videoDescription string No Optional description overlay. Supports legacy format codes.
videoDescriptionPosition string No topLeft, topRight, bottomLeft, bottomRight. Default bottomLeft.
titleTextScale float No Multiplier applied to the title font. Default 1.0.
descriptionTextScale float No Multiplier applied to the description font. Default 1.0.
textBoxOpacity float No 0.01.0 opacity of the box behind the title/description. Omit for the legacy auto alpha.
videoVolume float No 0.01.0 volume for this entry. Default 1.0.
transition string No Transition applied when entering this entry from the previous one. cut (default) or fadeOut/In. Ignored for the first entry.
nextAt float No Time in seconds (from the start of this entry) at which to cut/transition to the next entry. Omit to wait for the video to end naturally.

transition is a property of the incoming entry: if videos[1].transition = "fadeOut/In", the player fades videos[0] out while fading videos[1] in. cut is an instant frame-perfect swap.

Example

{
  "configVersion": 3,
  "firstJoin": {
    "repeatableInSameSession": false,
    "playlistLoop": false,
    "videos": [
      {
        "source": "videos/intro_part1.mp4",
        "skippable": true,
        "enableBackground": true,
        "colorBackground": "#FF000000",
        "videoTitle": "&6&lWelcome",
        "videoTitlePosition": "topLeft",
        "videoDescription": "&fEnjoy your journey",
        "videoDescriptionPosition": "topLeft",
        "titleTextScale": 1.4,
        "textBoxOpacity": 0.5,
        "videoVolume": 0.8,
        "nextAt": 8.0
      },
      {
        "source": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "skippable": true,
        "videoVolume": 1.0,
        "transition": "fadeOut/In"
      }
    ]
  },
  "playerDeath": {
    "repeatableInSameSession": true,
    "videos": [
      { "source": "videos/death/default_death.mp4", "videoTitle": "&cYou Died" }
    ]
  },
  "totemUsed": {
    "repeatableInSameSession": true,
    "videos": [
      { "source": "videos/totem.mp4", "videoTitle": "&eSaved by a Totem" }
    ]
  },
  "bedSleep": {},
  "entityKilled": {
    "minecraft:warden": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/kills/warden.mp4", "skippable": false, "videoTitle": "&5&lEpic Victory" }
      ]
    }
  },
  "deathByEntity": {
    "minecraft:creeper": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/death/creeper_death.mp4", "videoTitle": "&aBoom..." }
      ]
    }
  },
  "advancementCompleted": {
    "minecraft:story/mine_diamond": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/advancements/diamond.mp4", "videoTitle": "&bDiamonds!" }
      ]
    }
  },
  "dimensionChanged": {
    "minecraft:the_nether": {
      "repeatableInSameSession": true,
      "playlistLoop": true,
      "videos": [
        { "source": "videos/dimensions/nether_loop.mp4", "videoLoop": true, "videoTitle": "&cEntered the Nether" }
      ]
    }
  },
  "itemObtained": {
    "minecraft:diamond": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/items/first_diamond.mp4", "videoTitle": "&bFirst Diamond" }
      ]
    }
  },
  "itemCrafted": {
    "minecraft:crafting_table": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/items/first_table.mp4", "videoTitle": "&6Crafting Table" }
      ]
    }
  },
  "recipeUnlocked": {
    "minecraft:furnace": {
      "repeatableInSameSession": false,
      "videos": [
        { "source": "videos/recipes/furnace.mp4", "videoTitle": "&7Furnace Unlocked" }
      ]
    }
  },
  "scoreboard": {
    "kills": {
      "repeatableInSameSession": false,
      "value": 100,
      "comparator": "greaterOrEqual",
      "videos": [
        { "source": "videos/scoreboard/100_kills.mp4", "videoTitle": "&c100 Kills!" }
      ]
    }
  },
  "custom": {},
  "consumedConditionSessions": []
}

Config safety: a single malformed entry never wipes the file. Entries are parsed leniently — a bad one is skipped and logged, while every valid entry is kept. On a JSON syntax error the file is left untouched and defaults are used only in memory for that session, so you can fix the typo without losing your work.


⚙️ Common Configuration (conditionalvideos-common.json)

Controls client playback behavior. Created automatically with safe defaults.

Property Type Default Description
videoQuality string AUTO AUTO picks the best available stream. Any other value (LOWEST, LOW, MEDIUM, HIGH, HIGHEST) forces that quality. Only affects multi-variant sources (YouTube and similar).
alwaysShowCursor boolean false When true, the playback screen never auto-hides the mouse cursor.
allowGameSounds boolean false When true, vanilla Minecraft sounds keep playing during a video (muted by default).
blockMatureContent boolean true When true, mature-content sources are blocked. Client-only — a server cannot override it.
debugLogging boolean false When true, emits detailed [CV/...] diagnostics. Leave off for normal play; turn on only to troubleshoot.

In multiplayer, videoQuality, alwaysShowCursor and allowGameSounds come from the server's common config when available; blockMatureContent and debugLogging are always read from the local client file.


⌨️ In-Game Controls

By default the skip key is unbound, which falls back to ESC. You can bind a dedicated key under Options → Controls → Conditional Videos; that key then becomes the only active skip key and the on-screen hint always shows its name.

Other behavior: the cursor auto-hides after a few seconds of inactivity (unless alwaysShowCursor), vanilla sounds are muted while a video is on screen (unless allowGameSounds), and toast notifications are hidden during playback.


🧑‍⚖️ Server Commands

Available to permission level 2+ (command blocks, OPs) and the server console:

/conditionalvideos play <targets> <condition>
/conditionalvideos stop <targets>
/conditionalvideos pause <targets>

Condition keys use a bare key for simple conditions (firstJoin, playerDeath, totemUsed, bedSleep) or a type/key form for keyed ones, e.g. entityKilled/minecraft:warden, advancement/minecraft:story/mine_diamond, dimension/minecraft:the_nether, scoreboard/kills, custom/my_event.

The command/API keys for advancement and dimension use the advancement/... and dimension/... prefixes, while the config JSON stores them under the advancementCompleted and dimensionChanged maps.


🌍 Localization

UI and command strings ship in en_us, es_es, es_ar and es_mx. Add more by dropping a <locale>.json into a resource pack under assets/conditionalvideos/lang/.


🧰 Developer API

Other mods can register custom conditions and trigger / control playback through a small, stable public API in the org.mateof24.conditionalvideos.api package.

Quick facts

Install steps are the general flow for this file type — How to install Minecraft Java mods & modpacks walks through it step by step.

Verified by MCModsHub

These come from our own check of the pack file, not from the source page.

Explore more