{"id":50903777,"url":"https://github.com/hatimhtm/night-market-tycoon","last_synced_at":"2026-06-16T05:05:28.877Z","repository":{"id":357108101,"uuid":"1235046717","full_name":"hatimhtm/night-market-tycoon","owner":"hatimhtm","description":"Idle/tycoon HTML5 web game — 20 businesses, 13 upgrades, 13 achievements, prestige loop. Vite + vanilla JS + Tailwind 4 + break_eternity.js. 3-platform ad-SDK abstraction (CrazyGames / GameDistribution / Y8). Source-available under PolyForm Noncommercial.","archived":false,"fork":false,"pushed_at":"2026-05-11T10:00:37.000Z","size":2593,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T12:07:19.305Z","etag":null,"topics":["break-eternity","browser-game","crazygames","gamedistribution","howler","html5-game","idle-game","polyform-noncommercial","source-available","tailwindcss","tycoon","vanilla-js","vite","web-game"],"latest_commit_sha":null,"homepage":"https://hatimhtm.github.io/night-market-tycoon/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hatimhtm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T00:48:26.000Z","updated_at":"2026-05-11T10:00:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hatimhtm/night-market-tycoon","commit_stats":null,"previous_names":["hatimhtm/night-market-tycoon"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/hatimhtm/night-market-tycoon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fnight-market-tycoon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fnight-market-tycoon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fnight-market-tycoon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fnight-market-tycoon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hatimhtm","download_url":"https://codeload.github.com/hatimhtm/night-market-tycoon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hatimhtm%2Fnight-market-tycoon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34391761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["break-eternity","browser-game","crazygames","gamedistribution","howler","html5-game","idle-game","polyform-noncommercial","source-available","tailwindcss","tycoon","vanilla-js","vite","web-game"],"created_at":"2026-06-16T05:05:28.042Z","updated_at":"2026-06-16T05:05:28.867Z","avatar_url":"https://github.com/hatimhtm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets-readme/hero-banner-dark.svg\" /\u003e\n    \u003cimg src=\"assets-readme/hero-banner.svg\" alt=\"Night Market Tycoon\" width=\"100%\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://hatimhtm.github.io/night-market-tycoon/\"\u003e\u003cimg src=\"https://img.shields.io/badge/▶_PLAY_NOW-CCFF00?style=for-the-badge\u0026labelColor=1A1A1A\u0026logoColor=1A1A1A\" alt=\"Play Now\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/hatimhtm/night-market-tycoon/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/hatimhtm/night-market-tycoon/ci.yml?branch=main\u0026style=for-the-badge\u0026label=CI\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"CI\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Vite-7-1A1A1A?style=for-the-badge\u0026logo=vite\u0026logoColor=CCFF00\" alt=\"Vite 7\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Tailwind-4-1A1A1A?style=for-the-badge\u0026logo=tailwindcss\u0026logoColor=CCFF00\" alt=\"Tailwind 4\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Vanilla_JS-1A1A1A?style=for-the-badge\u0026logo=javascript\u0026logoColor=CCFF00\" alt=\"Vanilla JS\" /\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/LICENSE-POLYFORM_NC-1A1A1A?style=for-the-badge\u0026labelColor=1A1A1A\u0026color=CCFF00\" alt=\"PolyForm Noncommercial\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://hatimhtm.github.io/night-market-tycoon/\"\u003e\n    \u003cimg src=\"portal-assets/1280+720.jpg\" alt=\"Night Market Tycoon — splash\" width=\"80%\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eAn idle / tycoon browser game with 20 businesses, 13 upgrades, 13 achievements, a prestige loop, and a 3-platform ad-SDK abstraction. ~2,000 LOC of vanilla JS on Vite — no framework, single-file production bundle, runs offline once loaded. Built for CrazyGames / GameDistribution / Y8 / Poki distribution. Source-available under PolyForm Noncommercial.\u003c/em\u003e\n\u003c/p\u003e\n\n---\n\n### `/// THE LOOP`\n\n```\n       click an icon\n            │\n            ▼                                  hire a manager\n   ┌──────────────────┐                              │\n   │  progress bar    │  ◀────────────────────────────┘   buy more of\n   │  fills, cash $   │                                   the business\n   │  drops in        │  ─────────────────▶  buy upgrades, hit milestones,\n   └──────────────────┘                       speed bars by 2×\n            │\n            ▼\n   accumulate $1T total  ──▶  prestige  ──▶  Reputation Stars\n                                              (+2% profit / star, permanent)\n            │\n            ▼\n   unlock more businesses, achievements,\n   each achievement adds +1-5% profit forever\n```\n\nStandard idle-game DNA but tuned: **20 businesses** spanning vending machines to bazaar empires, **5 milestones per business** (25/50/100/250/500 owned → speed doublings), **13 upgrades** including the apex `VIP Lounge` (×10 global profit), **13 achievements** that each grant permanent stacking bonuses, **prestige loop** at $1T total earned, and **offline progress** for up to 7 days at 75% efficiency so leaving the tab open isn't the optimal strategy.\n\n---\n\n### `/// WHAT'S IN THE BOX`\n\n| | |\n|---|---|\n| **`break_eternity.js`** for the math | All money is Decimal. Numbers go to ~`1e1000` cleanly, with a custom `fmt()` that switches to K/M/B/T/Qa/Qi notation. |\n| **3 ad SDKs, one abstraction** | `src/ad-sdk.js` — flip a single constant (`AD_PLATFORM = 'crazygames'` / `'gamedistribution'` / `'stub'`) and the same code targets CrazyGames, GameDistribution, or Y8 (stub for portals that handle ads themselves). |\n| **Rewarded-ad reward = 2h of current MPS** | Industry standard. Cooldown 3 min between watches. |\n| **Howler.js audio** with 50 ms rate-limit per channel | Clicks/hovers don't machine-gun. Mute persists across sessions. |\n| **Save export/import** | Settings → \"Copy save to clipboard\". Move between browsers / back up a run. |\n| **Tamper-resistant saves** | Base64 + simple hash so save edits via DevTools fail the integrity check on load. |\n| **Achievement toasts** | Slide-in toast notifications when a new achievement unlocks. |\n| **Keyboard shortcuts** | `1`–`6` switch tabs, `M` mute, `P` prestige, `Esc` close any modal. |\n| **Mobile-friendly** | Single-column layout below 700px, larger touch targets, smaller toasts. |\n| **Single-file build** option | `vite-plugin-singlefile` available for portals that require one HTML upload. |\n\n---\n\n### `/// PROJECT LAYOUT`\n\n```\nnight-market-tycoon/\n├── index.html                          shell — left panel, tab bar, modals\n├── style.css                           ~2k lines of game CSS, fully themed\n├── package.json                        vite + tailwind 4 + break_eternity + howler\n├── vite.config.js                      arm64/x86-friendly, single chunk output\n├── src/\n│   ├── main.js                         init · game loop · tab renderers · shortcuts\n│   ├── state.js                        money, prestige, achievements, save export/import\n│   ├── businesses.js                   20 business defs · cost / profit / time math\n│   ├── managers.js                     auto-runner per business\n│   ├── upgrades.js                     13 upgrades (some with prerequisites)\n│   ├── achievements.js                 13 achievements + bonus calc\n│   ├── audio.js                        howler wrapper with rate limiting\n│   └── ad-sdk.js                       3-platform ad SDK abstraction\n├── assets/\n│   ├── images/                         business icons (32 PNGs, mostly Freepik)\n│   ├── audio/                          ogg sounds (click / buy / unlock / etc.)\n│   ├── particles/                      spark + star particle PNGs\n│   └── ranks/                          rank001..003 (Apprentice → Tycoon)\n├── portal-assets/                      submission images at portal specs\n│                                       (1280×550, 1280×720, 1920×1080, 200×120, …)\n└── assets-readme/                      brutalist banner SVGs (light + dark)\n```\n\n---\n\n### `/// 2.0 — THE OVERHAUL`\n\nThe 1.0 build (15 businesses, 7 upgrades, no achievements, no stats) shipped to portals. 2.0 is a substantial expansion, not a polish pass:\n\n**Content:**\n- **20 businesses** (was 15) — late-game tier from Pop-up Stall to Bazaar Empire.\n- **13 upgrades** (was 7) — new tier includes Neon Signage, Rush Hour, Night Lights, Chain Synergy, Sanitation II (prereq: Sanitation), VIP Lounge.\n- **13 achievements** (new system) — each grants a permanent additive bonus (+1–5%) stacked on top of prestige stars.\n\n**Systems:**\n- **Stats tracking** — total clicks, total play time across sessions, biggest cash, biggest MPS, prestige count, first played, businesses/managers/upgrades bought.\n- **Save export/import** — copy a Base64 string to clipboard, paste into another browser.\n- **Toast notification system** — slide-in notices for achievements and save events.\n- **Keyboard shortcuts** — `1`–`6` tabs, `M` mute, `P` prestige, `Esc` modal close.\n- **Achievement check loop** — runs once per second; cheap, defensive (a bad getter doesn't take the game down).\n- **Rank titles** — Apprentice / Vendor / Vendor II / Vendor III / Tycoon / Tycoon II / Mogul / Mogul Prime — three rank images mapped to eight title tiers.\n- **Stacked cost discounts** — Sanitation II is gated behind Sanitation; cost-scaling drops 1.15 → 1.10 → 1.08.\n- **Offline progress capped at 75%** — playing actively now always feels better than idling.\n\n**UX:**\n- Three new tabs in the right panel: **Achievements · Stats · Settings**.\n- \"Max\" multiplier no longer says \"Buy \" when you can't afford one — shows \"Need $X\" instead.\n- Achievement unlocks play the unlock SFX and pop a toast.\n- Settings tab has copy-save-to-clipboard + import-from-clipboard buttons.\n\n---\n\n### `/// LOCAL DEV`\n\n```bash\nnpm install\nnpm run dev       # vite dev server on :5173\nnpm run build     # production bundle to dist/\nnpm run preview   # serve dist/ on :4173 to smoke-test the build\n```\n\nRequires Node 20+. The build uses relative paths (`base: './'`) so the same `dist/` works on GitHub Pages, itch.io, CrazyGames, or any subdirectory deploy. Every push to `main` redeploys [the live demo](https://hatimhtm.github.io/night-market-tycoon/) via the CI workflow.\n\n---\n\n### `/// AD-SDK INTEGRATION`\n\n`src/ad-sdk.js` exports `initAds()` and `showRewardedAd()`. Switch platforms by changing one constant:\n\n```js\nexport const AD_PLATFORM = 'crazygames'; // 'gamedistribution' | 'crazygames' | 'stub'\n```\n\nFor GameDistribution builds, include the SDK script in `index.html` and pass `gameId` to `initAds()`. For CrazyGames, the SDK is loaded lazily by the abstraction. The `stub` mode is used for Y8 (which handles its own ads) and for local development — `showRewardedAd()` always resolves true after a brief pause.\n\n---\n\n### `/// LICENSE`\n\n[PolyForm Noncommercial 1.0.0](LICENSE). In plain English:\n\n- ✅ Read it, study it, fork it for personal/non-profit use, share it among friends, learn from the math.\n- ❌ Don't repackage and sell it. Don't embed it in a paid product. Don't ship it under a different name on a portal monetised against the original work.\n\nIf you want commercial terms, [open an issue](../../issues) or [book a call](https://cal.com/hatimelhassak/engineering-discovery).\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://hatimelhassak.is-a.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/PORTFOLIO-1A1A1A?style=for-the-badge\u0026logo=vercel\u0026logoColor=CCFF00\" alt=\"Portfolio\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://cal.com/hatimelhassak/engineering-discovery\"\u003e\u003cimg src=\"https://img.shields.io/badge/BOOK_A_CALL-CCFF00?style=for-the-badge\u0026logo=googlecalendar\u0026logoColor=1A1A1A\" alt=\"Book a call\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.linkedin.com/in/hatim-elhassak/\"\u003e\u003cimg src=\"https://img.shields.io/badge/LINKEDIN-1A1A1A?style=for-the-badge\u0026logo=linkedin\u0026logoColor=CCFF00\" alt=\"LinkedIn\" /\u003e\u003c/a\u003e\n  \u003ca href=\"mailto:hatimelhassak.official@gmail.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/EMAIL-1A1A1A?style=for-the-badge\u0026logo=gmail\u0026logoColor=CCFF00\" alt=\"Email\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ccode\u003e///\u0026nbsp;\u0026nbsp;OPEN FOR NEW WORK\u0026nbsp;\u0026nbsp;///\u0026nbsp;\u0026nbsp;CONTRACT \u0026amp; FREELANCE\u0026nbsp;\u0026nbsp;///\u0026nbsp;\u0026nbsp;REMOTE WORLDWIDE\u0026nbsp;\u0026nbsp;///\u003c/code\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatimhtm%2Fnight-market-tycoon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhatimhtm%2Fnight-market-tycoon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhatimhtm%2Fnight-market-tycoon/lists"}