Skip to content

Instantly share code, notes, and snippets.

@isXander
Created May 13, 2025 19:37
Show Gist options
  • Save isXander/22227a025f9489e1ee0f0e5cd2762927 to your computer and use it in GitHub Desktop.
Save isXander/22227a025f9489e1ee0f0e5cd2762927 to your computer and use it in GitHub Desktop.
This is an example of how Minecraft Java might implement data-driven GUI screens.
```json
// minecraft/gui/components/server_list.json
{
"params": {
"servers": { // `Type`
"type": "minecraft:list", // `Type`
"item_type": { // `Type`
"type": "minecraft:compound",
"components": { // `map<name, Type>`
"name": "minecraft:component",
"motd": "minecraft:component",
"server_id": "minecraft:string"
}
}
}
},
"item": {
"type": "minecraft:for_each",
"with_params": {
"list": "servers"
},
"item_name": "server" // e.g. java (server) -> {}, adds server param to scope
"iter": {
"type": "minecraft:server_entry",
"with_params": {
"name": "server.name",
"motd": "server.motd",
"server_id": "sever.server_id"
}
}
}
}
// minecraft/gui/components/server_entry.json
{
"params": { // params can dynamically change if they're provided from java, their state automatically triggers UI updates
"name": "minecraft:component",
"motd": "minecraft:component", // for example, the java backend could auto update the motd
"server_id": "minecraft:string"
},
"handler": {
"join_server": { // this stub is implemented within java (could be a separate data file?)
"server_id": "minecraft:string"
}
},
"item": { // root component
"type": "minecraft:clickable", // this means minecraft:button can be composable with data as well
"click": {
"type": "minecraft:ref",
"ref": {
"id": "join_server",
"params": {
"with_params": { // an obj to put fields to obj from component params
"server_id": "server_id"
}
}
}
}
"item": {
"type": "minecraft:padding",
"x": 2,
"y": 2,
// padding (x and y), left, right, top, bottom could also be defined here
"item": {
"type": "minecraft:hstack",
//"gap": 2,
"alignment": "leading/centre/space-around/space-between/trailing"
"items": [
{
"type": "minecraft:image",
"ref": "id registered from java",
// OR
"sprite": "gui sprite"
},
{
"type": "minecraft:vstack",
"alignment": "space-around",
"gap": 2,
"items": [
{
"type": "minecraft:text",
"with_params": {
"text": "name" // references params at the top
}
},
{
"type": "minecraft:text",
"with_params": {
"text": "motd"
}
}
]
}
]
}
}
}
}
@isXander
Copy link
Author

This Gist goes to show the real complexity in implementing a real, powerful, data-driven API for Minecraft screens. I don't see it happening any time soon.

You'd need to implement

  • A type system
  • 2-stage populate, eval system to populate params into the json before actually giving it to component codecs
    • populate may also be deep and recursive, adding to complexity
  • protections to limit the power of servers
  • a state tracking system
  • a responsive layout engine

Things to note

  • There is no distinction between Screens and Components here. Like the DOM, you simply present a component as the root component.
  • Clearly demonstrates that JSON is not a good format for this sort of thing
  • Completely misses key features of Minecraft GUIs, e.g. focusing, different behaviour based on specific state like focus, keyboard navigation, hover effects
    • This is potentially solved using minecraft:if and implicit params with this info, where the state is tracked and the GUI is automatically refreshed upon change
  • Primitives such as minecraft:image would be implemented on Java, rather than being data-driven.
  • Every single styling element, outline, padding, etc would need a wrapping component. Frameworks such as SwiftUI solve this using extension functions that wrap their receiver as their returns
  • Very fiddly param system, breaking out into conditional logic is very verbose, doing generic math like multiplication? I haven't thought about this.

@isXander
Copy link
Author

At what point are you just re-implementing a whole programming language in JSON?
A better solution would be to instead rely on a scripting interpreted language, instead of JSON. Like Lua, or JS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment