Zircon: a JVM tile engine and text GUI for roguelikes
Zircon is an extensible and user-friendly, multiplatform tile engine.
At a glance
- What is it?
- Zircon is a Kotlin and Java tile engine with a text GUI component library, published on Maven Central, that renders a grid of tiles, handles input, layers components and ships built-in tilesets and colour themes. It also runs on Compose Multiplatform and Korge, so the same tile application can target a desktop window or a JVM target other than Swing.
- Who is it for?
- Zircon suits a Java or Kotlin developer building a roguelike, a text interface or any tile-based UI who wants components, layers and colour themes instead of drawing to a canvas by hand. It is the wrong tool for a game that needs sprites and animation in the graphics sense rather than in the character-cell sense, and the wrong choice if you need a runtime that is not the JVM.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 121 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Zircon is and who builds games with it
Zircon is described as an extensible and user-friendly, multiplatform tile engine, and the README's own summary of the API reference gives the reason a developer would reach for it: a tile engine plus a text GUI, in one library.
The text GUI part is what distinguishes it from a general rendering library. Rather than drawing pixels, you place components such as labels, panels and checkboxes onto a grid of cells, and the engine handles the layout, the theming and the input focus. The Best Practices section in the README shows the design in one line: if you want to build something that is part of the public API, there is almost certainly a Builder or a factory object for it, with a newBuilder function on each type that has one.
The audience is fairly specific and the README makes it explicit in the project's own promotional link, which asks whether you plan to make a roguelike. The topic tags name game-development, java, jvm, kotlin, multiplatform, roguelike, scala and text-gui, and the Scala tag is worth noting, because it shows the API was designed to be usable from several JVM languages rather than Kotlin only.
The primary language is Kotlin, the licence is Apache-2.0, and the homepage is the Zircon page on the Hexworks projects site. The last push was on 2026-06-24 and the repository has no GitHub releases, so the published artefact is the Maven Central coordinate rather than a tag.
Adding Zircon as a dependency
The README gives both Maven and Gradle coordinates, and they are worth reading closely because the artefact names tell you about the multiplatform structure.
For Maven, the core artefact is zircon.core-jvm and the Swing implementation is zircon.jvm.swing.
<dependencies>
<dependency>
<groupId>org.hexworks.zircon</groupId>
<artifactId>zircon.core-jvm</artifactId>
<version>2021.1.0-RELEASE</version>
</dependency>
<!-- use zircon.jvm.libgdx if you want to use LibGDX instead of Swing -->
<dependency>
<groupId>org.hexworks.zircon</groupId>
<artifactId>zircon.jvm.swing</artifactId>
<version>2021.1.0-RELEASE</version>
</dependency>
</dependencies>The Gradle form is the same two coordinates.
dependencies {
implementation "org.hexworks.zircon:zircon.core-jvm:2021.1.0-RELEASE"
implementation "org.hexworks.zircon:zircon.jvm.swing:2021.1.0-RELEASE"
}Two things stand out. The core artefact carries a -jvm suffix, which is the JVM target of a multiplatform project that also has other targets. And the comment names a third option, zircon.jvm.libgdx, for anyone who would rather render through LibGDX than Swing, which is a reasonable choice for a game that already uses LibGDX for something else.
One caveat to carry. The version in these snippets is 2021.1.0-RELEASE, while the repository is several releases further on, so the coordinates in the README are an example rather than the current version. Check Maven Central for the coordinate you actually want before pinning one.
Building a TileGrid and a Screen
The basic usage example is short enough to read in full, and it shows the three objects you work with.
public class Main {
public static void main(String[] args) {
// a TileGrid represents a 2D grid composed of Tiles
TileGrid tileGrid = SwingApplications.startTileGrid(
AppConfig.newBuilder()
// The number of tiles horizontally, and vertically
.withSize(60, 30)
// You can choose from a wide array of CP437, True Type or Graphical tilesets
// that are built into Zircon
.withDefaultTileset(CP437TilesetResources.rexPaint16x16())
.build());
// A Screen is an abstraction that lets you use text GUI Components
// You can have multiple Screens attached to the same TileGrid to be able to create multiple
// screens for your app.
Screen screen = Screen.create(tileGrid);
// Creating text GUI Components is super simple
Label label = Components.label()
.withText("Hello, Zircon!")
.withAlignment(ComponentAlignments.alignmentWithin(tileGrid, ComponentAlignment.CENTER))
.build();
// Screens can hold GUI components
screen.addComponent(label);
// Displaying a screen will make it visible. It will also hide a previously shown Screen.
screen.display();
// Zircon comes with a plethora of built-in color themes
screen.setTheme(ColorThemes.arc());
}
}The TileGrid is the window, sized in cells, 60 by 30 here, and it is started through a platform-specific factory, SwingApplications here, with a configuration builder that takes the size and the default tileset. The tileset is one of the built-in ones, and the example picks a CP437 REXPaint set at 16 by 16.
The Screen is the layer you put content on, and the comment makes the model clear: multiple screens can be attached to the same TileGrid, so you can have separate screens for different views of the same application, and displaying a screen makes it visible while hiding a previously shown one.
The Component is a label, created through a static factory on Components rather than a constructor, with its text and its alignment set through the builder. The alignment is computed relative to the grid, and then the component is added to the screen. The theme is set on the screen, and the built-in themes are described as a plethora, with ColorThemes.arc() used here.
The API organisation and the utility classes
The Best Practices section is really an API tour, and the guidance is that the public API is in one package with a consistent shape.
Everything intended to be public lives in the org.hexworks.zircon.api package. Where several classes of the same kind exist, they are grouped into a single utility class. Components gives you builders for every component, so Components.panel() or Components.checkBox() rather than a constructor per component. DrawSurfaces does the same for TileGraphics and TileImage. Shapes creates the different Shape objects, and the README suggests your IDE will help you find these.
The naming convention is a consequence of that design. Anything you can build has a builder, and each type with a builder has a newBuilder function you can call, such as Tile.newBuilder(). The result is a fluent API where construction is uniform across the whole surface, which is a genuine advantage in a library this size.
For external files such as tilesets or REXPaint files, the README points at the same api package for the relevant utilities, so the resource loading is part of the public surface as well.
The repository itself is organised in the same spirit, with zircon.core/ as the engine, zircon.compose/ and zircon.examples.compose/ for the Compose target, zircon.korge/ and zircon.examples.korge/ for the Korge target, alongside the examples and the Gradle build files. A compose directory and a Korge directory in the same repository are the clearest statement of what multiplatform means here.
The feature set and the documented road map
The README's table of contents is effectively the feature list, and it is worth walking through what each heading implies.
Drawing is the foundation, and it is tile based, so everything is positioned on a cell grid. Input handling covers keyboard and mouse, and the fact that it is a separate section implies that the engine routes input to components rather than to the application, which is what makes a text GUI usable.
Layering is the third structural feature, and it is what lets a screen hold a hierarchy of components, a background and a foreground, in the way a desktop toolkit does.
Text GUI Components is the section that covers the widget set, and the basic usage example already shows labels, panels and check boxes. Animations is a separate section, and there is an ANIMATIONS.md file at the root of the repository, which suggests the animation support is documented in its own right. Shape and Box Drawing covers the primitive drawing operations that the tileset and shape APIs expose. Fonts and Tilesets covers the resource layer, with the README mentioning CP437, True Type and graphical tilesets built in.
The README also links a road map as a named section, and there are PROGRESS.md, TODO.md, PROJECTS.md and nerd.md files at the root, which is an unusually open set of planning documents for a game engine. The Examples site is described as under construction, and the recommended starting point for learning by doing is the Zircon Crash Course rather than the API documentation.
Where Zircon is the wrong choice
The first limitation is that it is a character-cell engine, not a sprite engine. Everything is drawn on a grid of cells using a tileset, which is exactly right for a roguelike or a text interface and exactly wrong for a game that needs smooth sprite animation, particle effects or arbitrary artwork. Choosing Zircon for that is choosing the wrong rendering model, and no amount of configuration fixes it.
The second is the JVM dependency. The primary language is Kotlin and the whole thing runs on the JVM, which means a runtime dependency and a build that needs a JVM toolchain, in exchange for a cross-platform story that is really a story about which JVM targets and which Compose and Korge targets you can reach.
The third is the split between the README and the current release. The dependency coordinates in the documentation are 2021.1.0-RELEASE, and the examples reference an API shape that has presumably moved on. A reader following the README literally may hit mismatches against the current artefact, and the documentation site is the more reliable source.
The fourth is the maturity signals. The examples page is described as under construction, the road map is a forward-looking document rather than a description of a finished thing, and the repository has no GitHub releases, so the release history has to be read from Maven Central.
The fifth is that the last push was on 2026-06-24, roughly four months ago, which is a normal gap for a library rather than a project in trouble, but it does mean a bug you find may sit for a while.
Zircon compared with Lanterna, with libGDX and with a Compose canvas
Lanterna is the closest comparison for the text GUI half, since it is the other established JVM text terminal and TUI library. The difference in approach is that Zircon is a full tile engine first, with the component system built on top of a tile grid and a tileset, so the same code that draws a character can draw a sprite from a graphical tileset, while Lanterna concentrates on character cells and terminal capabilities.
libGDX is the comparison for the game half, and here Zircon is not competing directly but sitting alongside it. The README's own comment about zircon.jvm.libgdx is telling: if you want to use LibGDX instead of Swing, there is an artefact for that. So the intended arrangement is that a project that already uses libGDX for physics or audio can use Zircon for the tile rendering and the UI.
Korge and Compose Multiplatform are the third comparison, and they are on a different axis. Both are cross-platform game and UI frameworks with their own rendering, and Zircon now has modules for both, which is how a Kotlin multiplatform project can share the same tile UI code between a desktop JVM target and a native or web target.
The fourth is a plain Swing or JavaFX application. If the interface is a form with a handful of fields, a desktop toolkit is faster to reach for and does more, and Zircon's advantage appears only when the interface is genuinely a grid of cells, where the tileset and the components are the natural abstraction.
Licence, community and what to check before you start
The licence field on the repository says Apache-2.0, and the README carries the same licence badge. A permissive licence with a patent grant is a comfortable fit for a library that a commercial game might embed, and the LICENSE file is at the root.
The project is not archived and the last push was on 2026-06-24, so it is being maintained, if not at high frequency. The release history is available through Maven Central rather than through GitHub releases, and the Maven badge in the README points at the org.hexworks.zircon/zircon.core artefact.
The community channels are set out in the README header: a Discord server, a project board, and an issue tracker, plus a Patreon link for supporting the project. The Javadoc and Kdoc are published at hexworks.github.io/zircon/, and there is a contributor guide, a code of conduct and an issue template in the repository. The AUTHORS file and the credits section are also part of the layout, which is what you would expect from a project with a decade of contributions.
Four things to check before you write anything.
The version to depend on. Take the coordinate from Maven Central rather than from the README, because the snippets there are from the 2021.1.0 line.
Which platform module you want, with zircon.jvm.swing as the default and zircon.jvm.libgdx as the alternative, and Compose or Korge if you are going multiplatform.
Which tileset and theme to start with, since the built-in set is large and picking one early means you are not redrawing later.
And whether the skeleton project fits you, since the Java and Kotlin skeleton repositories are described as coming with batteries included, and starting from one of those is faster than assembling a project from the dependency snippets.
Editorial conclusion
Zircon suits a Java or Kotlin developer building a roguelike, a text interface or any tile-based UI who wants components, layers and colour themes instead of drawing to a canvas by hand. It is the wrong tool for a game that needs sprites and animation in the graphics sense rather than in the character-cell sense, and the wrong choice if you need a runtime that is not the JVM. Before adopting it, check the version you would pull, because the coordinates in the README's dependency snippets are from the 2021.1.0 line while the repository itself is several releases further on.
Frequently asked questions
What is Zircon?
It is an extensible, user-friendly, multiplatform tile engine written in Kotlin and Java for the JVM, with a text GUI component library on top. It provides a grid of tiles, input handling, layering, animations, shape and box drawing, fonts and tilesets, and built-in color themes.
How do I add Zircon to a Maven project?
Add the org.hexworks.zircon group with the zircon.core-jvm artefact, and the platform module such as zircon.jvm.swing or zircon.jvm.libgdx, depending on which renderer you want. The README's Maven and Gradle snippets use version 2021.1.0-RELEASE, so check Maven Central for the current coordinate before pinning one.
What are the main objects in the Zircon API?
A TileGrid represents the two dimensional grid of tiles, a Screen is an abstraction you attach to a grid to hold GUI components, and components such as labels, panels and check boxes are created through factory objects. The grid is started with a platform-specific call such as SwingApplications.startTileGrid with an AppConfig that sets the size and the default tileset.
Which platforms does Zircon support?
The repository contains zircon.core alongside zircon.compose, zircon.korge and their example modules, and the published artefacts are JVM ones such as zircon.core-jvm and zircon.jvm.swing, with zircon.jvm.libgdx as an alternative renderer. The primary language is Kotlin and the topics name Java, JVM, Kotlin, Scala and multiplatform.
How do I learn the Zircon API?
The README points at the Zircon Crash Course as the best place to start, then the official documentation site, the examples page and the API reference. If you prefer learning by doing, the source of the examples is in the repository under zircon.jvm.examples for both Java and Kotlin, and skeleton projects are available for both languages.
What licence is Zircon released under?
Apache-2.0, with the terms in the LICENSE file at the root of the repository.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/hexworks-zircon)Was this useful?