← Roadmap

EffectiveScreenEffects experimental

Experimental part: the API may change, behaviour across clients and with shader packs is not guaranteed.

Screen effects

Why

Screen fade and camera shake are cutscene tools: hide a teleport, sell an explosion, stun. Bukkit has no fade at all, and shake is done with teleports that jerk the player.

EffectiveScreenEffects draws the fade with a full-screen glyph from the framework pack and sends shake as a relative rotation packet — the camera trembles, the player does not move.

EffectiveScreenImage and EffectiveScreenText go further: an image or text at any point of the screen. The framework pack overrides the text core shader, and position and size travel in the character colour — the client needs nothing but the resource pack.

Minimal example

Fade with teleport
EffectiveScreenEffects.runCameraFade(player, fadeIn = 10, stay = 20, fadeOut = 10) {
    player.teleport(arenaSpawn)
}
Shake
EffectiveScreenEffects.runCameraShake(player, intensity = 3f, duration = 40, type = ShakeType.EASE_OUT)

EffectiveScreenEffects.runCameraShake(player, intensity = 1f) { Arena.isRunning }
Image and text on screen
object Logo : EffectiveScreenImage() {
    override fun getNamespacedData() = MyPlugin.instance to "logo"
    override fun getTexturePath() = "textures/screen/logo.png"
    override fun getX() = 0.05f
    override fun getY() = 0.05f
    override fun getSize() = 0.25f
    fun init() {}
}

Logo.show(player)
Logo.show(player, durationTicks = 100)
Logo.hide(player)

EffectiveScreenText.show(player, "Wave 3", x = 0.5f, y = 0.1f, scale = 2f)

x, y are screen fractions from the top-left corner, size is a fraction of the screen width. Any PNG shape: the framework pads it to a square itself.

What to override

  • getNamespacedData() *
    EffectiveScreenImage: plugin and id
  • getTexturePath() *
    PNG inside the plugin jar
  • getX() / getY()
    Default: 0f
    Default position, screen fractions
  • getSize()
    Default: 0.25f
    Default width, screen fraction

* required

Pitfalls

  • EffectiveScreenImage and EffectiveScreenText are experimental: the core-shader technique, API and behaviour may change. Fade and shake are stable.
  • All of it is a title. Needs the framework resource pack enabled; without it the player sees a box or a bare character.
  • One title per player: image, text and fade override each other. For several elements at once, join the components into one title via getComponent().
  • Shader packs (Iris, OptiFine) replace core shaders — for those players the image/text will land in the wrong place. Fade and shake always work.
  • Shake ends with a compensating rotation — the camera returns to where it was.