Skills and Resources is an interactive exhibit about civil security preparedness. Visitors use physical NFC tokens to identify as one of several characters, each with unique skills and resources. Two side-by-side sub-apps let them manage their character's inventory and tackle scenario-based challenges (blackouts, storms, evacuations, etc.) to discover how personal preparedness makes a difference.
The exhibit consists of two parts:
- Web app (Vue 3 + Vite): Renders a
ChallengeAppand anInventoryAppside-by-side in a scaled letterbox layout (2 × 1080 × 1920). - Token reader tool (Node.js CLI): Bridges physical NFC/PC/SC smart card readers to the web app via a WebSocket server.
Runtime options are configured in
src/options/options.yaml. Options are currently
loaded at build time via @modyfi/vite-plugin-yaml; a future version will
support loading them at runtime.
languages.primary(default:"de"): Primary display languagelanguages.secondary(default:"en"): Secondary display languagewebsocketTokenReaderUrl(default:"ws://localhost:8382"): URL of the token reader WebSocket server
The exhibit configuration is split into two YAML files, both loaded at build
time via @modyfi/vite-plugin-yaml:
src/config/app.yaml— UI strings (section titles, descriptions, token prompt)src/config/content.yaml— exhibit content (items/skills/resources, character types, and challenges)
A JSON Schema for validating the configuration format is available at
specs/config.schema.json. The configuration is
validated against this schema during startup. A
third-party online viewer
for the schema is also available.
The token reader is a separate Node.js CLI tool in
tools/token-reader/ that bridges physical NFC/PC/SC
smart card readers to the web app via a WebSocket server. Install its
dependencies separately:
npm run fix-install --prefix tools/token-readerDo not use the standard npm install unless you are using Node.js >=20.20.0 <21
(the native dependency@pokusew/pcsclite requires this version range to compile
without patching the source code). Using the special fix-install script will make
it work with newer Node.js versions, though (tested using Node.js 24.1).
Run it from the repository root via the convenience script:
npm run token-reader -- <command>Available subcommands:
list: List connected NFC readers and exitserve: Start the WebSocket server (requires-iand-cflags to specify the inventory and challenge reader names)monitor: Connect to the WebSocket server and echo messagessimulate: Simulate token readers with a terminal UI (pass character uuid/name pairs as arguments)
Run npm run token-reader -- --help or
npm run token-reader -- <command> --help for detailed usage information.
The token reader tool currently only supports NTAG21x (NTAG 213/215/216) NFC tags. Each tag represents one character and must be prepared as follows:
-
Write an NDEF text record containing the character type ID (e.g.
character_1,character_2, …). The IDs must match thecharacterTypes[].idvalues insrc/config/content.yaml. The NDEF record must be of typetext— no other record types are supported. -
Enable the NFC counter (recommended). By reading the counter, it is possible to check whether a tag is approaching or has reached its end of life (NTAG21x tags are rated for 100 000 read operations). The NFC counter is controlled by bit 4 (
NFC_CNT_EN) of theACCESSconfiguration byte (byte 0 of page2Ahon NTAG213,84hon NTAG215,E5hon NTAG216). To enable it without overwriting other bits, first read the page with aREADcommand, set bit 4 in byte 0, and write the byte back:READ <ACCESS page> # e.g. 30 2A for NTAG213 # extract byte 0-3 of the 16 byte response # 00:05:00:00:00:00:00:... -> 00:05:00:00 # set bit 4 (0x10) of byte 0, but keep other bits unchanged # 00:05:00:00 | 10:00:00:00 -> 01:05:00:00 # write the modified byte back WRITE <ACCESS page> ... # e.g. A2 2A <modified 4 bytes> for NTAG213Once enabled, the 24-bit counter can be read with the
READ_CNTcommand (39h):39 02The reader returns 3 bytes representing the counter value in little-endian byte order.
Please consult the NTAG21x specification for more details about the
READ,WRITE, andREAD_CNTcommands as well as theACCESSconfiguration byte and theNFC_CNT_ENbit. -
Enable password protection (recommended). Setting a password makes the tag read-only for anyone who does not know the password. This prevents tech-savvy visitors from deleting or modifying the tag data using their smartphones.
On Android, the NFC Tools app can be used to write NDEF records and configure tag settings such as the read counter and password protection. Note that the read counter can only be enabled via the Advanced NFC commands, which may permanently damage the tag when used incorrectly.
Install dependencies and start the development server:
npm install
npm run devThe following npm run scripts are available:
dev: Start a development server with hot-reloadingbuild: Type-check and build for productionpreview: Preview the production build locallygenerate: Run all generate scriptsgenerate:config-schema: Generate JSON Schema from the TypeBox config schematypecheck: Run TypeScript type checking (vue-tsc)lint: Lint with oxlintlint:fix: Lint with auto-fixformat: Format code with oxfmt
The token reader tool has its own package.json in
tools/token-reader/. Install the dependencies via
npm run fix-installSee the Token Reader Tool section above for more details.
The following additional npm run scripts are available within that directory:
typecheck: Run TypeScript type checkinglint/lint:fix: Lint with oxlintformat: Format code with oxfmt
Developed by Christian Stussak and Andrea Heilrath for IMAGINARY gGmbH. Based on an idea by Eric Londaits.
Copyright (c) 2026 IMAGINARY gGmbH, licensed under the MIT license (see
LICENSE).