Making Wordii, a Pure Java Single-Page App
As 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 Picture
I 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 runmvn clean install
and
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 Logic
Wanting to separate the logic of handling game events and tracking guessed letters from the UI, I made anEngine
class.
This has methods like addToCurrentGuess()
and
startNewGame()
.
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 UI
Each of the six guesses is shown using a custom Flavour component calledGuessComponent
. 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 UI
The Stats UI is another Flavour template, with logic in theStatsView
class 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
is 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 Keyboard
The on-screen keyboard is provided by another component,OnScreenKeyboardComponent
with 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
Engine
provides the status for each key, and then this
component shares the CSS class with the guesses via a
Style
class.
State Saving
In a moment of inspired creativity, I named a classState
to 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 Numbers
Wordii'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 © 2024 Andrew Oliver