Making Wordii, a Pure Java Single-Page AppAs I write this in February of 2022, the 5-letter word game craze is in full effect. When I saw some of them, I thought, as did many others, "I could do that". Aware that much complexity can lie under the covers, I decided to see for myself what was really involved. The end result is Wordii, a 5-letter word game with infinite words and speed running stats.
What did it take? What tools did I use? All is revealed below.
The Big PictureI have been using TeaVM for many years to build native web apps in Java. For single-page apps, I rely on TeaVM's accompanying framework Flavour. I started from the Flavour maven archetype, which makes it easy to get a maven project going with everything already in place. You get a small web page with some dynamic content, and the POM file is fully set up to execute the TeaVM transpilation process. Just run
mvn clean installand your SPA is ready to open in a browser in seconds. There's a full article on getting started with TeaVM in Java Magazine.
Once the skeleton was in place, it was time to flesh out the rest of the project:
- Guess Logic
- Guess UI
- Stats UI
- On-Screen Keyboard
- State Saving
Guess LogicWanting to separate the logic of handling game events and tracking guessed letters from the UI, I made an
Engineclass. This has methods like
The engine also updates the letter states as guesses are submitted, and tracks stats as games are completed, including multi-game streak best scores. All values are maintained in the state, which the engine saves frequently so the game can be restarted at any time without loss of progress.
Guess UIEach of the six guesses is shown using a custom Flavour component called
GuessComponent. Bound to an HTML template called
guess.html, GuessComponent returns the letters of the guess, and provides the CSS classes to use for each letter. There are different classes for the five possible states of a letter: no letter, presubmit, wrong, wrong-position, or correct.
Stats UIThe Stats UI is another Flavour template, with logic in the
StatsViewclass and the template HTML in
stats.html. The HTML and CSS handle layout, with the statistics coming from the state via StatsView class methods invoked via Flavour's expression language (EL).
StatsView also has several buttons. The most interesting
Share, which uses the browser Clipboard API to copy a
message about the completed game to the clipboard for sharing via
e-mail or social media. The message contents are emojis, generated
via a call to the Engine.
On-Screen KeyboardThe on-screen keyboard is provided by another component,
OnScreenKeyboardComponentwith a corresponding HTML template. The rows of key letters are provided by the component class, and the template loops over them adding the keys one-by-one. Since the keys need to react to the guesses already made, the component provides style names to the template. The
Engineprovides the status for each key, and then this component shares the CSS class with the guesses via a
State SavingIn a moment of inspired creativity, I named a class
Stateto hold the application state. This class holds all of the lifetime statistics and the current game state (guesses, time elapsed, etc.).
The state is saved in Local Storage using the TeaVM Local Storage APIs. Flavour makes it easy to convert a POJO into JSON and back. Local storage is per-domain, and per-browser, so statistics are not easily portable from device to device.
By The NumbersWordii's source code breaks down as follows:
- Non-comment lines of Java: about 1000
- Non-comment lines of HTML: about 200
- Non-comment lines of CSS: about 60
- Images: 0 (emojis only)
Copyright © 2022 Andrew Oliver