<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n" -->

---
title: Dissecting Loottox: A Gacha Streaming Service | daily.dev
description: A developer walkthrough of Loottox, a personal web-based gacha game built with Express v5 and vanilla JavaScript that lets users 'pull' for access to stream...
canonical: https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Dissecting Loottox: A Gacha Streaming Service | daily.dev
og:description: A developer walkthrough of Loottox, a personal web-based gacha game built with Express v5 and vanilla JavaScript that lets users 'pull' for access to stream...
og:url: https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n
og:image: https://api.daily.dev/og/posts/8klsfPH3n.png
og:image:alt: Dissecting Loottox: A Gacha Streaming Service
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Dissecting Loottox: A Gacha Streaming Service

**[Medium](https://daily.dev/sources/medium_js)** · 8 min read · 2 upvotes · 0 comments

## Summary

A developer walkthrough of Loottox, a personal web-based gacha game built with Express v5 and vanilla JavaScript that lets users 'pull' for access to stream music files. The post covers the transaction flow system, RNG-weighted rarity pools using Fisher-Yates shuffle, cookie-based session management, song streaming with wavesurfer.js, and word-synced lyrics via a custom TTML parser. The author shares honest reflections on hacking together a client-server architecture for a fun personal project.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@toxidev/dissecting-loottox-a-gacha-streaming-service-296d4206411a>

## Questions this post answers

### How can I implement weighted rarity selection like in gacha games using JavaScript?

Build a range map from percentage rates in a rates file, converting cumulative percentages into thresholds (e.g., 0-50% common, 51-75% uncommon, 76-90% rare, 91-100% legendary). Generate a random number between 0 and 100, then iterate through thresholds to find which rarity band the roll falls into, returning that rarity for pool selection.

_Developers building loot or reward systems can find similar implementation walkthroughs curated on daily.dev._

### How does the Fisher-Yates shuffle work for randomizing item pools by rarity in JavaScript?

Items are first grouped into pools by rarity category, then each pool array is shuffled in place using the Fisher-Yates algorithm: iterate from the last index down to 1, pick a random index from 0 to the current index, and swap the two elements. Once shuffled, songs can be selected via a simple pop() call for guaranteed randomness without repeats.

_daily.dev surfaces practical algorithm writeups like this for developers implementing randomization logic._

### How can I track user sessions using both IP address and User-Agent instead of just cookies?

A transaction lookup checks both the IP address and User-Agent string against active transactions before falling back to creating a new one, allowing a returning device or network to be matched to an existing session even without a valid cookie. The resulting transaction ID is then set as a non-httpOnly cookie with a matching expiry, defaulting to 12 hours.

_Engineers designing session or transaction tracking can find backend design breakdowns like this on daily.dev._

## Similar posts on daily.dev

- [There's a dungeon under this blog](https://daily.dev/posts/there-s-a-dungeon-under-this-blog-q9utaeyuv) · Lobsters · 3 upvotes · 1 comments
- [6in6 Part III](https://daily.dev/posts/6in6-part-iii-tklbedbke) · Medium · 0 upvotes · 0 comments
- [Run Rob Run: Building a Music-Reactive Goo with Three.js and WebGPU](https://daily.dev/posts/run-rob-run-building-a-music-reactive-goo-with-three-js-and-webgpu-mruzhhr1p) · Codrops · 3 upvotes · 0 comments
- [The groove is the 40 milliseconds a grid throws away, so we built a beat studio that gives them back, in a browser tab](https://daily.dev/posts/the-groove-is-the-40-milliseconds-a-grid-throws-away-so-we-built-a-beat-studio-that-gives-them-back-fiaruwgvg) · DEV · 9 upvotes · 0 comments

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#javascript](https://daily.dev/tags/javascript), [#authentication](https://daily.dev/tags/authentication), [#express](https://daily.dev/tags/express)

[View this post on daily.dev](https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Dissecting Loottox: A Gacha Streaming Service","url":"https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n"},"datePublished":"2026-07-27T02:56:37.304Z","dateModified":"2026-09-13T19:54:06.399Z","description":"A developer walkthrough of Loottox, a personal web-based gacha game built with Express v5 and vanilla JavaScript that lets users 'pull' for access to stream...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8426571cee9f39e7f233950fafb991db?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8426571cee9f39e7f233950fafb991db?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":2},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"webdev,javascript,authentication,express","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Dissecting Loottox: A Gacha Streaming Service"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/dissecting-loottox-a-gacha-streaming-service-8klsfph3n#faq","mainEntity":[{"@type":"Question","name":"How can I implement weighted rarity selection like in gacha games using JavaScript?","acceptedAnswer":{"@type":"Answer","text":"Build a range map from percentage rates in a rates file, converting cumulative percentages into thresholds (e.g., 0-50% common, 51-75% uncommon, 76-90% rare, 91-100% legendary). Generate a random number between 0 and 100, then iterate through thresholds to find which rarity band the roll falls into, returning that rarity for pool selection. Developers building loot or reward systems can find similar implementation walkthroughs curated on daily.dev."}},{"@type":"Question","name":"How does the Fisher-Yates shuffle work for randomizing item pools by rarity in JavaScript?","acceptedAnswer":{"@type":"Answer","text":"Items are first grouped into pools by rarity category, then each pool array is shuffled in place using the Fisher-Yates algorithm: iterate from the last index down to 1, pick a random index from 0 to the current index, and swap the two elements. Once shuffled, songs can be selected via a simple pop() call for guaranteed randomness without repeats. daily.dev surfaces practical algorithm writeups like this for developers implementing randomization logic."}},{"@type":"Question","name":"How can I track user sessions using both IP address and User-Agent instead of just cookies?","acceptedAnswer":{"@type":"Answer","text":"A transaction lookup checks both the IP address and User-Agent string against active transactions before falling back to creating a new one, allowing a returning device or network to be matched to an existing session even without a valid cookie. The resulting transaction ID is then set as a non-httpOnly cookie with a matching expiry, defaulting to 12 hours. Engineers designing session or transaction tracking can find backend design breakdowns like this on daily.dev."}}]}
```

