Skip to content

The Basics

vini2003 edited this page Jul 4, 2020 · 1 revision

Example / Walkthrough

Spinnery is a GUI library for Minecraft 1.15 to 1.16. Written to be severely abstracted to allow for quick porting and less dependency on Minecraft code, it is by all means a fairly capable framework, not directly based on existing models. Effectively, it can be subdivided as seen in the following graph:

While complicated at first, the architecture, to the end user, is simple. I'll show you some of the basics and then a complete example - sounds good to me.

The Basics

In Spinnery, you may have Screens or ContainerScreens. Effectively, a Screen is something only meant to be shown to the client - a perfect fit for annoying popups on player spawn - please don't actually do that.

A ContainerScreen (known outside Spinnery as a HandledScreen) is a screen meant to be displayed on the client, but that requires information from the server. That'd be Chests, Furnaces, Beacons, you know, that sort of stuff. Behind any ContainerScreen, there's a Container (known outside Spinnery as a ScreenHandler), which holds the actual shared data - slots and stuff.

Whenever you're making a ContainerScreen, you're gonna need to add shared widgets in both the ContainerScreen and the Container (slots, mainly), except you only need positions and sizes in the ContainerScreen. Onto positions and sizes, then!

Position

A Position is an object holding x, y and z coordinates. They may be fixed, anchored or supplied. For a quick summary, suppose we have a widget button at position 8, 8, 0 (x, y, z):

  • Fixed: a position based on a raw coordinate.
Position myPosition = Position.of(64, 64, 0);

This position is always at 64, 64, 0.

  • Anchored: a position based on a widget's position.
Position myPosition = Position.of(button, 24, 24, 0);

Can you take a guess what that does? It means that whenever its position is requested, it'll do my X plus their X, my Y plus their Y, my Z plus their Z, so, in this case, 8 + 24, 8 + 24, 0 + 0 -> 32, 32, 0. This is useful for simple offsets, but sometimes you need more complex positioning. That's where our next buddy comes in:

  • Supplied: a position based on coordinate suppliers.
Position myPosition = Position.of(() -> screenWidth / 2f, () -> screenHeight() / 2f, () -> 0f);

This one's a bit more complicated and means you must know how Java lambdas work. Basically, whenever the coordinates are requested, it runs that bit of code; so if it wants x, it will return screenWidth / 2f. Of course, actually running it every time would be bad for performance, so I've fixed that up in the backend to recalculate the coordinates only when needed.

Size

A Size is an object holding width and height numbers. In other words, it dictates the literal size of a widget, and has two options - fixed and supplied.

  • Fixed: a size based on the given numbers.
Size mySize = Size.of(32, 32);

The above size will be 32 by 32, always. Of course, again you may need a more complex way to decide siding, so our buddy appears again.

  • Supplied: a size based on number suppliers.
Size mySize = Size.of(() -> parentWidth / 3f, () -> parentHeight / 3f);

As you may have guessed, this means that, whenever this size is asked about its width, it'll run that bit of code - again, that's not quite how it works in the backend, but you don't have to worry about that.

Clone this wiki locally