Hacking JSX: Building in Minecraft with React
From Author:
When combined with a custom rendering function, JSX can be used to quickly build a custom domain-specific markup language. I will show you how to approach this using the example of creating builds in Minecraft.
This talk has been presented at React Day Berlin 2023, check out the latest edition of this React Conference.
FAQ
JSX is a way of writing pseudo-HTML code within JavaScript code. It needs to be transpiled into something the browser can understand, typically a call to React's react.createElement() function.
A domain specific language (DSL) is a programming language designed to do one thing particularly well, unlike general-purpose languages like JavaScript that can solve any problem. Examples include SQL for databases and HTML for web page structure.
JSX can be used to create builds in Minecraft by converting JSX syntax into game commands. This involves creating a custom JSX handler function that converts the JSX into an array of objects or commands understood by the game.
There are two main reasons: 1) Familiarity with JSX means there is no steep learning curve, and 2) Existing tooling for JSX, such as parsers, linters, and IDE support, can be leveraged, eliminating the need to write custom tools.
The react.createElement() function is what JSX is transpiled into when using React. It converts JSX syntax into React elements that the browser can understand.
Yes, JSX can be used outside of React by using a custom function that has the same signature as react.createElement(). This allows for custom behavior and use cases.
The intermediary representation is a way to convert JSX syntax into a different format, such as an array of objects or classes. This format can vary depending on the problem being solved.
In Minecraft, blocks are placed using three coordinates: x, y, and z. Each block also has a type, defined by an ID value.
Using JSX for creating custom languages offers advantages like familiarity, reducing the learning curve, and leveraging existing tooling for parsing, linting, and IDE support.
The source code for the JSX Minecraft build project is available on GitHub.
Video Transcription
1. Using JSX for Minecraft Builds
Hello React Day, I will be talking about how we can use JSX to create builds in Minecraft. JSX is a way of writing pseudo-HTML code within JavaScript code. It can be transpiled into something that the browser can understand. JSX is not limited to React and can be used with other functions. It allows for the creation of an intermediary representation that can be converted into commands for Minecraft. Using JSX for building a custom DSL is beneficial because it is familiar to developers and has a low learning curve.
Hello React Day, my name is Felix and I will be talking about how we can use JSX to create builds in Minecraft. Furthermore, I will also be exploring the idea of using JSX as domain specific language in general.
So first of all, what even is a domain specific language? A domain specific language or DSL for short, it's a programming language that is designed to do one thing particularly well. And that is in contrast to a general purpose programming language such as for example JavaScript, which in theory is able to solve every problem.
So take for example SQL. SQL is very good at interacting with databases in a very concise manner, but it is overall limited in functionality and isn't able to solve every problem. Or in other words, SQL isn't Turing complete. Another very famous example for a domain specific language is HTML. HTML is designed to define the structure of a web page. But since we are talking about JavaScript and React here, we aren't able to use HTML directly. Instead, we use something called JSX.
JSX is a way of writing pseudo-HTML code within JavaScript code. But since browsers don't natively support JSX, this JSX syntax needs to be first transpiled into something that the browser can in fact understand. And this is, in the case of React, a call to a function called react.createElement() which then, in the end, represents the same content as our JSX does. But the great part about JSX is that we aren't limited to using it with React. Instead, we can use whatever function instead of React.createElement() to then use JSX and add custom behavior to it.
So in this case, I first of all create a custom block component which then gets fed into my custom JSX handler function, in this case a minecraft JSX function. And this works because my function has the exact same function signature as react.createElement() Therefore, I can take my function as target for transpolation from JSX. In this example here, I've expanded this example and also wrapped it in a fragment. And now the idea is that with my custom JSX handler, I'm able to convert this JSX syntax into an array consisting of plain objects. But now that's the important part. Depending on the use case or the problem that you're trying to solve, this intermediary representation may look completely different. You may want to use classes instead or possibly preserve the nesting that was created by JSX. This intermediary representation will greatly depend on the problem you're trying to solve.
I'm able to convert this array into a set of commands which are understood by the game and then turned into an actual build within Minecraft. In case you don't know, Minecraft is a 3D sandbox game where you can place blocks wherever as defined by three coordinates, x, y and z. And each block of course has a type, in this case it's defined by this ID value.
So therefore in general, the question why would you use JSX for building a custom DSL. The first reason is that you and your colleagues are already familiar with JSX. Therefore there isn't a great learning curve and it's easy to adopt.
2. Using JSX for Minecraft Builds - Part 2
You can rely on existing tooling when using JSX, eliminating the need for custom parsers and enabling linting and IDE support. The apply build function converts JSX builds into game elements, similar to mounting a React tree to an HTML DOM element. Building with JSX is easy and familiar, as demonstrated by the readable house component. Running the app with bun allows for real-time rendering of the build. If you create something using JSX, please share it with me. The source code for this project is available on GitHub.
And probably, number two, way more important, you can rely on existing tooling. So for example you don't need to write a custom parser for transforming your JSX markup into the final result. Instead, you can just write that JSX handler and be done. You don't need to write a language parser. And also you can rely on existing tooling for linting or also for IDE support, because JSX is widely supported across tooling.
So, what does this look like in a greater picture? Here I've created an apply build function which in the end is what converts my build, as defined here in JSX, into something that's actually in the game. And you can think of this similarly to mounting your React tree to an HTML DOM element when using React regularly. And now with this village component, this is just plain JSX, as I told you. It is very easy to get into the idea of building something with JSX, because you already are familiar with it. Like here, this house component is just a collection of other components, that is, as I think, very readable overall.
So now if I run this app with bun, because bun has built-in JSX support, I can effectively watch as my build sort of gets rendered to the game. Ok, that's it. I hope I could give you a little insight of an idea of how you can use JSX for whatever purpose you want. If you end up building something, or building a custom language effectively on JSX, I'd love to see what you are creating. So please reach out to me, I'd love to see it. And the source code for this project that I just showed you is available on github.
Check out more articles and videos
We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career
Comments