Case Study  ·  Travel & Tourism  ·  Italy

NipsApp Game Studios built a travel risk engine that can explain every single point it awards

An Italian travel and tourism client needed software that tells a traveller how fragile their trip is before it falls apart, and walks them through it when it does. We delivered a deployed platform and a companion game with a deterministic scoring engine, a bilingual interface, and zero third-party dependencies.

0Third-party dependencies
628Automated checks, all passing
9Explainable risk factors
2Languages, parity enforced by test

01Project summary

Who it was for, and what shipped.

ClientTravel and tourism sector, Italy (named under NDA)
ProductsQemuro Travel Risk & Rescue System, plus Journey Quest, a gamified companion PWA
EngagementFixed-scope functional prototype, delivered, deployed and handed over
TeamNipsApp Game Studios, full-stack delivery including architecture, build, QA and documentation
LanguagesItalian and English throughout, including all generated documents
HostingEuropean region, always-on instance with a persistent disk and daily backups
Live Platform  ·  Journey Quest

02The problem

Why travellers only find out once it is too late.

A missed connection is rarely a surprise in hindsight. The 35-minute gap between a landing and a ferry was always going to be tight, but nothing told the traveller while there was still time to change it. And once a trip breaks, the traveller improvises: which number to call, what to photograph, what to write, what they are actually entitled to claim.

Our client wanted both halves solved in one product. Alongside that came a constraint that shaped every technical decision afterwards: the score had to be explainable. Not a confidence interval. Not a model output. A number where a traveller can ask “why?” and get a real answer.

Why that constraint is harder than it sounds

An explainable score cannot hide behind averages. If the engine says a connection is risky, it has to name the minutes and the reasons. That forces every rule into the open, where it can be argued with, and where being wrong is visible. Most risk products avoid this precisely because it is uncomfortable.

03What we built

Four parts, one shared engine.

A risk engine with no black box

Qemuro uses no statistical model. It composes the minimum connection time from the steps a traveller actually performs: leaving the aircraft, reclaiming a checked bag, crossing between terminals or across a city, boarding, plus extra minutes for travellers with children, older travellers, or anyone needing assistance. Because the minimum is composed, it can be explained. Every connection carries a breakdown showing the minutes step by step and the rule behind each one.

Nine scoring factors sit on top: connection buffer, change of locality, change of terminal, checked baggage, missing data, traveller profile, airport procedures, multimodal sea legs, and whether a leg is the last service of the day. Weights are tunable from the back office, and every score records the configuration version that produced it, so a number from last month can still be reproduced.

Guided recovery, not a help page

Nine disruption scenarios, each producing a three-tier A/B/C action plan with deadlines, a bilingual message the traveller can copy and send to a carrier, and an evidence checklist. Every recommended action is tagged by reliability: established fact, needs checking, estimate, or suggestion. A catch-all scenario handles what no list anticipates: secure the position, document it, formalise it in writing.

Evidence that holds up later

Uploaded tickets, receipts and photographs are categorised, hashed with SHA-256 for integrity, and assembled into a downloadable dossier. The PDF is generated server-side and is byte-identical for identical input, which matters when a document may need to support a claim months afterwards.

A game that teaches the same judgement

Journey Quest puts the player through six Italian journeys where every decision spends time, budget, energy and composure. The risk engine is visible before each choice, and there are no dice: if the score crosses the threshold, the complication always happens. A bad outcome can therefore always be foreseen, and avoided, which is exactly the habit the platform is trying to build. Progress is stored against the player's account rather than the browser, so it survives a change of device.

04Technology stack

Not libraries we chose. Things we wrote.

The whole system runs on the Node.js standard library. No framework, no build step, no package manager at runtime.

LayerImplementation
RuntimeNode.js, standard library only. dependencies: {} and devDependencies: {} are both empty.
Front endVanilla JavaScript, hand-written CSS, no bundler. The files served are the files written.
DatastoreJSON with atomic writes, plus versioned and tracked migrations that run once and record themselves.
PDF generationPDF 1.4 writer built from scratch: Helvetica AFM metrics, WinAnsi encoding, Flate compression, cross-reference tables, deterministic output.
EmailSMTP client written against RFC 5321: implicit TLS or STARTTLS upgrade, AUTH PLAIN and LOGIN, RFC 2047 header encoding so Italian accents survive.
BackupsPOSIX ustar TAR writer plus gzip, with a restore proven byte-identical by test, including binary attachments and accented filenames.
Off-site storageAWS Signature V4 implemented with node's crypto module, so any S3-compatible provider works with no lock-in.
Time zonesIANA zones resolved through Intl with a two-pass daylight-saving boundary resolution, so a connection across a clock change is still correct.
SecuritySalted password hashing, single-use expiring tokens stored hashed, role checks enforced server-side, full audit log.
OfflineService worker with stale-while-revalidate and content-hash asset versioning, so a deploy can never be masked by a cache.
DeliveryContinuous integration on every push, auto-deploy from the main branch, persistent disk in a European region.

Why zero dependencies was the right call here

This was not minimalism for its own sake. The client is receiving a codebase they will own and operate. Zero dependencies removes supply-chain vulnerabilities, packages abandoned by their maintainers, version conflicts at deploy time, and third-party licences to audit. There is nothing to update and nothing to renew. Five years from now the code still installs, because there is nothing to install.

05The hard parts

Including the ones that were our fault.

A risk model that was quietly too optimistic

The first engine used one flat minimum per pair of transport modes. That allowed 20 minutes to leave an aircraft and ignored checked baggage entirely, so a 30-minute connection between a flight and a bus scored as comfortable. The client, testing a real Naples to Capri route, said it did not match reality. She was right.

The fix, and what it exposed

Rebuilding the minimum as composed steps corrected the score, and exposed a second fault: a flight into Naples followed by a ferry from Naples was being treated as a zero-minute transfer, because the place names matched. An airport and a port are not the same building. Both are now costed, and both are visible to the traveller.

A fix that shipped but never arrived

The client reported that the game's English translation was incomplete. It was not: it had been complete for days. Every cached asset carried a content hash in its URL so a release could not be served stale, except the game's own scripts, which were the one thing left out. Her phone received the new shell and the old code. The bug was invisible to us and total for her.

This is the failure mode worth naming, because it makes a supplier look careless when they are not. The lesson stuck: every cacheable asset is now stamped, without exception.

Two applications, one cache

The platform and the game share an origin. The service worker answered every navigation with the platform's shell, so opening the game landed on the platform, and worse, the game's page was then cached in the platform's place. Each application now keeps its own offline shell.

Email that was never actually sent

The mailer had a clean seam for swapping in a production sender. Nothing ever called it. Password reset links were written to the server log and reached nobody, while the interface told the user a link was on its way. We found it by asking a question we should have asked sooner: does this work where the client will use it, not where we test it? A full SMTP client now ships, and the back office reports in red when delivery is not configured, so it cannot fail silently again.

A game mission that could not be won

Simulating every mission along the most cautious path revealed that one of the six was mathematically impossible to complete that way: the two lowest-risk choices consumed its entire time budget. The game was punishing exactly the behaviour it existed to teach. Balance is now enforced by a test that fails the build if any mission becomes unwinnable by careful play.

A responsive rule that was never applied

The dashboard rendered 531 pixels wide on a 375-pixel phone. The rule that should have prevented it existed, and was correct, but was cancelled by a later rule with equal specificity further down the stylesheet. It had never once taken effect. A test now fails the build if any responsive override is defeated by stylesheet order.

Language that leaked between languages

An English message to a carrier read “Due to Ritardo”, because a cause typed in Italian was being dropped into an English sentence. Free text cannot be translated at render time, so the cause became a structured choice with proper phrasing in each language. Names and descriptions still stay in the traveller's own words, where that is correct.

06How we proved it works

628 checks, run against the live system.

The project carries 628 automated checks: 568 unit and integration tests, plus a 60-check acceptance suite that walks the product the way a real user does. The acceptance suite can be pointed at the deployed instance rather than a local copy, which is the only version of “it works” that means anything to a client.

That suite signs in as all three roles and confirms what each may and may not reach, creates a trip and its segments, checks the score and its explanation, opens a disruption event and drives it through resolution and reopening, confirms one user cannot see another's data, and verifies everything survives signing out and back in.

Tests that exist because a bug taught us to write them

  • Fails if a responsive CSS rule is silently cancelled by stylesheet order.
  • Fails if the risk engine can produce a finding the interface offers no way to act on.
  • Fails if untranslated text reaches the markup, or a stored value is printed raw to a user.
  • Fails if any game mission becomes unwinnable by cautious play.
  • Fails if scoring and the delay simulator ever disagree about the same connection.
  • Fails if two simultaneous identical requests create two records instead of one.

Verified on the screens people actually own

Every screen was checked at 320, 360 and 375 pixels in both languages, measured rather than eyeballed: real word widths against real container widths, page overflow against viewport width, and each language scanned for text belonging to the other. A separate compatibility report documents what was covered, the minimum browser versions the product needs, and, just as importantly, what was not covered.

07Built to be handed over

A prototype nobody can operate is not an asset.

This one shipped with twelve technical documents, including an architecture guide, a data model, a risk engine specification with test cases, an API reference, an operations runbook, a deployment guide, and an administrator manual written for the person running the platform rather than the person who built it.

  • Versioned migrations that run once and record themselves, so a redeploy never reapplies them.
  • Server-enforced permissions across three roles, because hiding a button is not access control.
  • Daily backups with 14-day retention and a restore proven byte-identical, including binary files.
  • GDPR handling: consent logged against the exact version of the text accepted, one-click export, and deletion that states what it will destroy before asking.
  • No lock-in: no keys in the code, a readable datastore, and configuration entirely in environment variables.

08Results

What the client received.

  • Delivered and deployed, running in a European region with a persistent disk and automated daily backups.
  • Every review item closed. Fourteen items across the client's formal technical review matrix, plus three further rounds of test feedback.
  • 628 checks passing, with the acceptance run executed against the live instance rather than a local build.
  • Bilingual throughout, with a test that fails the build if the two languages fall out of step.
  • Documented for handover, including an operations manual for non-technical staff.
Nel complesso il flusso è migliorato molto ed è più completo e chiaro… sono molto contento del lavoro svolto, per la collaborazione e la serietà messa fino adesso.
Client feedback, August 2026 “Overall the flow has improved a great deal and is more complete and clearer… I am very happy with the work, the collaboration and the professionalism shown so far.”

09Questions we are often asked

The ones that come up in every first call.

What is a deterministic travel risk score?

It is a score calculated from fixed, published rules rather than a statistical model. The same itinerary always produces the same number, and every point traces back to the rule that added it. Qemuro scores nine factors, including connection buffer, change of locality, checked baggage and whether a leg is the last service of the day.

Can software predict weather or natural disasters affecting a trip?

No, and Qemuro deliberately does not try. It measures how much margin an itinerary has, which is what decides whether a disruption breaks the trip regardless of its cause. A connection with 15 minutes of slack fails under any disruption; one with 90 minutes absorbs it. Two factors do weight structural exposure: sea legs, and the last connection of the day.

Why would a product avoid third-party libraries entirely?

Because the client has to live with them. Zero dependencies means no supply-chain vulnerabilities, no abandoned packages, no version conflicts on deploy, and no external licences to audit. For a codebase handed over as an asset, that is worth more than the development time an import would have saved.

Do you build gamified companion apps alongside core products?

Yes. Journey Quest exists because the platform asks travellers to change a habit, and a game teaches a habit faster than a tooltip does. It shares the platform's principles: the same explainable engine, the same bilingual content, and progress stored against the user's account rather than the browser.

Can you work with a client in another language and time zone?

This entire engagement ran in Italian and English, with the client reviewing on her own phone and reporting in Italian. Every generated document, every user-facing message and every legal text ships in both languages, and a test fails the build if they diverge.

Have a product that needs to be right, not just finished?

We build software that can explain itself: deterministic where it matters, tested against the live system, and documented well enough to hand over and walk away.

Start a project →

ABOUT NIPSAPP

NipsApp Game Studios is a full-cycle game development company founded in 2010, based in Trivandrum, India. With expertise in Unity, Unreal Engine, VR, mobile, and blockchain game development, NipsApp serves startups and enterprises across 25+ countries.

🚀 3,000+ Projects Delivered 121 Verified Clutch Reviews 🌍 25+ Countries Served 🎮 Since 2010

SERVICES

GAME GRAPHICS DESIGN

VR/XR SIMULATION

TALENT OUTSOURCING

RESOURCES

WORK SAMPLES

CONTACT US

India Office:

Viddhya Bhavan, Panniyode Road, Vattappara, Trivandrum, Kerala, India

Email: [email protected]

Phone: +91 62384 72255

Apple Maps Icon View on Apple Maps Google Maps Icon View on Google Maps

UAE Office:

Office No: 102, Near Siemens Building, Masdar Free Zone, Masdar City, Abu Dhabi, UAE

COPYRIGHT © 2026 NipsApp Game Studios | Privacy Policy | Terms & Conditions | Refund Policy | Privacy Policy Product |
Facebook Twitter LinkedIn Instagram YouTube