<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nenad Nikolić</title>
    <description>The latest articles on DEV Community by Nenad Nikolić (@turnkit-dev).</description>
    <link>https://dev.to/turnkit-dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3814850%2Fa928178e-53d9-40f4-a1fe-112bb780e92d.png</url>
      <title>DEV Community: Nenad Nikolić</title>
      <link>https://dev.to/turnkit-dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/turnkit-dev"/>
    <language>en</language>
    <item>
      <title>Turn-Based Game Server Options in 2026: An Honest Comparison for Indie Developers</title>
      <dc:creator>Nenad Nikolić</dc:creator>
      <pubDate>Wed, 15 Apr 2026 21:32:47 +0000</pubDate>
      <link>https://dev.to/turnkit-dev/turn-based-game-server-options-in-2026-an-honest-comparison-for-indie-developers-4ona</link>
      <guid>https://dev.to/turnkit-dev/turn-based-game-server-options-in-2026-an-honest-comparison-for-indie-developers-4ona</guid>
      <description>&lt;p&gt;Full disclosure: I'm the creator of TurnKit, a purpose-built authoritative relay for turn-based games. I've tried to keep this objective based on real development experience and public pricing (as of April 2026), let me know if I got something wrong or missed something.&lt;/p&gt;

&lt;p&gt;For indie turn-based multiplayer, the core trade-off is development speed versus authority (cheat protection, turn enforcement, hidden data handling). The practical paths break down into four distinct approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom Backend: Build full authority from scratch (e.g., Node.js/Go + database + WebSockets).&lt;/li&gt;
&lt;li&gt;Per-Match Servers: Spawn headless game instances per match (Unity Netcode, Mirror, Godot equivalents).&lt;/li&gt;
&lt;li&gt;Basic Relays: Pure message forwarding (Unity Relay, Photon PUN).&lt;/li&gt;
&lt;li&gt;Authoritative Relay: Lightweight server that enforces turns and filters data without running the full game engine (TurnKit is currently the dedicated implementation in this niche).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;General tools like Nakama or Colyseus require you to implement turn validation, hidden state, and signed results manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F064d7tkhgjwkhb01lamt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F064d7tkhgjwkhb01lamt.png" alt=" " width="768" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pricing comparisson:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtbaw6isdv2ja9lc3c7r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtbaw6isdv2ja9lc3c7r.png" alt=" " width="774" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basic relays tend to be the cheapest option at low scale, but they can become less attractive as player numbers grow or when cheating risk increases. An authoritative relay approach adds built-in protections while aiming to keep operational costs and complexity relatively low.&lt;/p&gt;

&lt;p&gt;Like any solution, this approach has limitations. In 1v1 matches, client voting systems can allow griefing where a losing player falsely votes to end the match. Similar risks of collusion exist in games with three or more players. Because of these trust boundaries, this type of lightweight authoritative relay is generally not recommended for games involving real money&lt;/p&gt;

&lt;p&gt;What backend or approach are you using (or considering) for your turn-based game? What has been your biggest pain point so far? Feel free to share in the comments. Did I get any of the pricings wrong or missed some option?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>gamedev</category>
      <category>networking</category>
    </item>
    <item>
      <title>How to Add a Leaderboard to Your Unity Game for Free (No Monthly Fees)</title>
      <dc:creator>Nenad Nikolić</dc:creator>
      <pubDate>Mon, 09 Mar 2026 13:41:14 +0000</pubDate>
      <link>https://dev.to/turnkit-dev/how-to-add-a-leaderboard-to-your-unity-game-for-free-no-monthly-fees-2828</link>
      <guid>https://dev.to/turnkit-dev/how-to-add-a-leaderboard-to-your-unity-game-for-free-no-monthly-fees-2828</guid>
      <description>&lt;h1&gt;
  
  
  How to Add a Leaderboard to Your Unity Game for Free (No Monthly Fees)
&lt;/h1&gt;

&lt;p&gt;Every game is better with a leaderboard. But the moment you go looking for a leaderboard backend, you hit a wall.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem With Existing Options
&lt;/h2&gt;

&lt;p&gt;The popular choices all have tradeoffs that don't suit indie developers well.&lt;/p&gt;

&lt;p&gt;**Firebase now has dedicated leaderboard support, but you're still on Google's infrastructure with Google's pricing — and no control over what changes next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LootLocker&lt;/strong&gt; has a genuinely generous free tier and is worth looking at. But you're still trusting a third party with your player data, and you have no control over pricing changes down the road.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nakama&lt;/strong&gt; is open source and free to self-host — but it's a full game server platform. If all you need is a leaderboard, the setup complexity is significant. It's a serious piece of infrastructure built for serious use cases.&lt;/p&gt;

&lt;p&gt;The underlying frustration is simple: a leaderboard is not a complicated thing. It's a sorted list of scores. Why does setting one up take an afternoon?&lt;/p&gt;




&lt;h2&gt;
  
  
  What If You Just Hosted It Yourself?
&lt;/h2&gt;

&lt;p&gt;Self-hosting sounds scary but the actual requirements for a leaderboard backend are modest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small server to run the API&lt;/li&gt;
&lt;li&gt;A PostgreSQL database to store scores&lt;/li&gt;
&lt;li&gt;A way to query rankings efficiently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No real-time sync, no complex state, no websockets. A leaderboard is fundamentally a read-heavy REST API backed by a database with a good index.&lt;/p&gt;

&lt;p&gt;The total hosting cost for this on free infrastructure: &lt;strong&gt;$0/month&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing RankDrop
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Brainzy/rankdrop" rel="noopener noreferrer"&gt;RankDrop&lt;/a&gt; is an open source, self-hosted leaderboard backend built specifically for this use case.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free forever&lt;/strong&gt; — Apache 2.0, no licensing fees, no usage limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production ready&lt;/strong&gt; — caching, connection pooling, atomic writes, health checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiny footprint&lt;/strong&gt; — GraalVM native image, ~118MB Docker image, ~50ms startup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works with any HTTP client&lt;/strong&gt; — Unity, Godot, mobile, web, desktop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple leaderboard types&lt;/strong&gt; — all-time, daily, weekly, monthly with automatic resets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible scoring&lt;/strong&gt; — high score wins, lowest time wins, or cumulative totals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Player moderation&lt;/strong&gt; — ban players, remove individual scores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook notifications&lt;/strong&gt; — Discord or Slack alerts when top scores are beaten&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You deploy it once, you own it forever.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Long Does This Actually Take?
&lt;/h2&gt;

&lt;p&gt;Here's an honest comparison:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Deploy&lt;/th&gt;
&lt;th&gt;Unity integration&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manual self-host (this tutorial)&lt;/td&gt;
&lt;td&gt;~20 min&lt;/td&gt;
&lt;td&gt;60 min&lt;/td&gt;
&lt;td&gt;~1.5 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RankDrop Unity Asset &lt;em&gt;(coming soon)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;included&lt;/td&gt;
&lt;td&gt;included&lt;/td&gt;
&lt;td&gt;60 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This tutorial covers the manual path — it's straightforward and completely free. If you'd rather skip the hour entirely, the &lt;a href="https://turnkit.dev" rel="noopener noreferrer"&gt;RankDrop Unity Asset&lt;/a&gt; handles both deploy and Unity integration in 60 seconds. Follow progress at &lt;a href="https://turnkit.dev" rel="noopener noreferrer"&gt;turnkit.dev&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deploying for Free on Koyeb + Aiven
&lt;/h2&gt;

&lt;p&gt;The easiest zero-cost path is &lt;strong&gt;Koyeb&lt;/strong&gt; (free app hosting) + &lt;strong&gt;Aiven&lt;/strong&gt; (free managed PostgreSQL). Both have permanent free tiers — not trials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Create a free PostgreSQL database on Aiven
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://aiven.io" rel="noopener noreferrer"&gt;aiven.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new &lt;strong&gt;PostgreSQL&lt;/strong&gt; service — select the free tier&lt;/li&gt;
&lt;li&gt;Once provisioned, copy the connection string from the service dashboard&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;defaultdb&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="n"&gt;sslmode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Deploy to Koyeb
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://koyeb.com" rel="noopener noreferrer"&gt;koyeb.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new app → select &lt;strong&gt;Docker&lt;/strong&gt; → use the image &lt;code&gt;ghcr.io/brainzy/rankdrop:latest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add your environment variables from &lt;code&gt;.env.example&lt;/code&gt;, substituting the Aiven connection string for the database URL&lt;/li&gt;
&lt;li&gt;Deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Koyeb will give you a public URL like &lt;code&gt;https://your-app.koyeb.app&lt;/code&gt;. That's your leaderboard API endpoint.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Koyeb's free tier sleeps after 60 minutes of inactivity and wakes in about 3 seconds on the next request. For most indie games this is fine — your leaderboard loads on the main menu, which wakes it up before the player notices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3 — Verify it's running
&lt;/h3&gt;

&lt;p&gt;Open your Koyeb URL + &lt;code&gt;/swagger-ui/index.html&lt;/code&gt; in a browser. You'll see the full interactive API docs. Create a leaderboard, submit a test score, query the rankings — all from the browser before writing a single line of Unity code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Calling the API From Unity
&lt;/h2&gt;

&lt;p&gt;RankDrop exposes a standard REST API. From Unity you call it with &lt;code&gt;UnityWebRequest&lt;/code&gt; — the same way you'd call any HTTP endpoint.&lt;/p&gt;

&lt;p&gt;The key endpoints:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you want&lt;/th&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Submit a score&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/leaderboards/{slug}/scores&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get top N scores&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/leaderboards/{slug}/top?limit=10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Get a player's rank + neighbours&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/leaderboards/{slug}/players/{alias}?surrounding=3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top scores + player context in one call&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/leaderboards/{slug}/combined&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;combined&lt;/code&gt; endpoint is the one you'll use most — it returns both the top of the leaderboard and the current player's position in a single request, which is exactly what a leaderboard UI needs.&lt;/p&gt;

&lt;p&gt;Full request/response schemas are in the Swagger UI once deployed.&lt;/p&gt;

&lt;p&gt;This is also where the hour goes in the manual path — writing the &lt;code&gt;UnityWebRequest&lt;/code&gt; wrappers, handling errors and timeouts, managing the game key, building a reusable service class. It's not hard, just time consuming. The &lt;a href="https://turnkit.dev" rel="noopener noreferrer"&gt;Unity Asset&lt;/a&gt; ships all of this pre-built.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multiple Leaderboard Types
&lt;/h2&gt;

&lt;p&gt;One of the most useful features for games is automatic periodic resets. RankDrop supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All-time&lt;/strong&gt; — scores persist forever&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily&lt;/strong&gt; — resets every day at midnight UTC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekly&lt;/strong&gt; — resets every Monday&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly&lt;/strong&gt; — resets on the 1st of each month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run multiple leaderboards simultaneously — one all-time, one weekly, one for a limited-time event — each with its own slug, scoring strategy, and reset schedule.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scoring Strategies
&lt;/h2&gt;

&lt;p&gt;Three modes out of the box:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best only&lt;/strong&gt; — only the player's highest score is kept. Perfect for high score games.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple entries&lt;/strong&gt; - Store every score submission as separate entries&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cumulative&lt;/strong&gt; — scores add up over time. Perfect for daily challenge points or XP totals.&lt;/p&gt;




&lt;h2&gt;
  
  
  Define more parameters if you want
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sorting by lowest time or highest value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;min and max scores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;archive options and many others&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  If You Outgrow the Free Tier
&lt;/h2&gt;

&lt;p&gt;Koyeb + Aiven handles the vast majority of indie games comfortably. If you do hit the free tier limits, the next step is any VPS with Docker — Hetzner, DigitalOcean, Fly.io. RankDrop is a single Docker container and runs anywhere.&lt;/p&gt;

&lt;p&gt;For serious scale, Oracle Cloud's free tier gives you 4 OCPU and 24GB RAM permanently — but most indie games will never need it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;RankDrop is the leaderboard foundation of &lt;strong&gt;&lt;a href="https://turnkit.dev" rel="noopener noreferrer"&gt;TurnKit&lt;/a&gt;&lt;/strong&gt; — a no-code multiplayer backend for turn-based games I'm building, including relay, matchmaking, and player economy. If you're making a card game, board game, or any turn-based multiplayer game, follow the build at &lt;a href="https://turnkit.dev" rel="noopener noreferrer"&gt;turnkit.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The RankDrop repo is at &lt;a href="https://github.com/Brainzy/rankdrop" rel="noopener noreferrer"&gt;github.com/Brainzy/rankdrop&lt;/a&gt;. Stars, issues, and feedback all welcome.&lt;/p&gt;

&lt;p&gt;If you run into any issues deploying, drop a comment below or join the &lt;a href="https://discord.gg/SqMVU5xex3" rel="noopener noreferrer"&gt;TurnKit Discord&lt;/a&gt; — happy to help you get it running.&lt;/p&gt;

&lt;p&gt;If you are interested in other options for leaderboards check out &lt;a href="https://www.turnkit.dev/leaderboard-options" rel="noopener noreferrer"&gt;https://www.turnkit.dev/leaderboard-options&lt;/a&gt; .&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #gamedev #unity #opensource #java&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>opensource</category>
      <category>java</category>
    </item>
  </channel>
</rss>
