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
EffectiveScreenEffects.runCameraFade(player, fadeIn = 10, stay = 20, fadeOut = 10) {
player.teleport(arenaSpawn)
}EffectiveScreenEffects.runCameraShake(player, intensity = 3f, duration = 40, type = ShakeType.EASE_OUT)
EffectiveScreenEffects.runCameraShake(player, intensity = 1f) { Arena.isRunning }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: 0fDefault position, screen fractions
- getSize()Default: 0.25fDefault 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.