coroutine-based kotlin minecraft game engine
at master 131 lines 3.2 kB view raw view rendered
1# Rendering API 2 3Axi provides a very extensible rendering API allowing you to 4render elements on a player's screen, be it an action bar, 5the chat or a boss bar. 6 7## Writing your own Renderable 8 9To make your own renderable element, you have to implement 10the `RedrawableRenderable` interface. 11 12## Writing a render function 13 14First up, we have to implement the `render` function. The 15`render` function is a suspending function that gets called 16on every redraw by this renderable and returns the contents 17that should be rendered on the player's screen. 18 19In our case, this will just return the current tick of the 20server: 21 22```kt 23object TickDisplay : RedrawableRenderable { 24 override suspend fun render(): TextComponent = buildText { 25 append(Bukkit.getCurrentTick()) 26 green() 27 } 28} 29``` 30 31## Writing a tick function 32 33This tick function will handle our redrawing logic. The 34`tickRedraw` function takes in the current `tick` of the 35server and returns a `RedrawResult`. This can either be 36`Redraw`, which forces this redrawable to be redrawn, 37`Dispose`, which removes this redrawable from the player's 38render state or `None` which does nothing. 39 40Let's redraw our tick display every other tick: 41 42```kt 43object TickDisplay : RedrawableRenderable { 44 override suspend fun render(): TextComponent = buildText { 45 append(Bukkit.getCurrentTick()) 46 green() 47 } 48 49 override suspend fun tickRedraw(tick: Int): RedrawResult { 50 return if (tick % 2 == 0) { 51 RedrawResult.Redraw 52 } else { 53 RedrawResult.None 54 } 55 } 56} 57``` 58 59Great! This will display the current server tick ten times a 60second. 61 62## Writing a renderer 63 64Axi currently provides two built-in renderers: 65 66- `Renderer.Actionbar`, which sends the stacked rendered 67component to an audience's action bar 68- `Renderer.Chat`, which "clears" an audience's chat by 69sending 16 empty lines and the stacked rendered component to 70an audience's chat. 71 72For the sake of this guide, let's re-implement the `Actionbar` 73renderer ourselves. `Renderer` is a functional interface that 74takes in an audience, the current renderable, and the already 75rendered stacked component. 76 77```kt 78val Actionbar = Renderer { audience, renderable, stacked -> 79} 80``` 81 82Now, let's actually send the stacked component using adventure's 83API: 84 85```kt 86val Actionbar = Renderer { audience, renderable, stacked -> 87 audience.sendActionBar(stacked) 88} 89``` 90 91Well, that was quite simple. Now let's actually use it in our 92renderable! 93 94## Using a renderer 95 96To use a renderer in our redrawable, we have to override the 97`renderer` field: 98 99```kt 100object TickDisplay : RedrawableRenderable { 101 override suspend fun render(): TextComponent = buildText { 102 append(Bukkit.getCurrentTick()) 103 green() 104 } 105 106 override suspend fun tickRedraw(tick: Int): RedrawResult { 107 return if (tick % 2 == 0) { 108 RedrawResult.Redraw 109 } else { 110 RedrawResult.None 111 } 112 } 113 114 override val renderer: Renderer = Renderer.Actionbar 115} 116``` 117 118## Displaying our renderable 119 120Now, let's actually display our renderable. To do this, we 121simply add it to an `Attachable`'s `RenderStateComponent`: 122 123```kt 124player.renderState.currentlyRenderedRenderables.add(TickDisplay) 125``` 126 127Axi also provides a utility for this: 128 129```kt 130player.addRenderable(TickDisplay) 131```