DEV Community

Tariq Mehmood
Tariq Mehmood

Posted on

Track Null’s Brawl Battle Logs Using Node.js

So, you’re deep into Null’s Brawl — enjoying unlimited gems, maxed-out brawlers, and all the skins you never had in the real game. But wouldn’t it be cool if you could track your battle logs, see how often you win, or even spot your most used brawlers in real-time?

Let’s build something useful: a Battle Log Tracker Bot that monitors your match history in Null’s Brawl, stores it, and gives you insights about your playstyle. We’ll use Node.js, Express, a fake battle log API simulation (since Null’s Brawl is a private server), and lowdb for local JSON-based data storage.

This is purely educational — for offline fun with Null's Brawl, not real Brawl Stars or for any competitive edge.

What You’ll Need

  • Node.js installed
  • Some knowledge of Express and async/await
  • curl or Postman to simulate API calls
  • A fake or emulated battle log API (we’ll mock this)
  • A text editor (VS Code preferred)
  • Coffee (because this is a long one!)

Step 1: Project Setup

mkdir nulls-brawl-log-bot
cd nulls-brawl-log-bot
npm init -y
npm install express axios lowdb dotenv node-cron
Enter fullscreen mode Exit fullscreen mode

Then create the following files:

touch server.js api.js db.js .env
Enter fullscreen mode Exit fullscreen mode

In .env, store your player tag:

PLAYER_TAG=#Y0URFAKETAG
Enter fullscreen mode Exit fullscreen mode

Step 2: Mocking a Battle Log API

Since Null’s Brawl doesn’t have a real public API, we’ll mock it for the sake of this bot.

Create api.js:

// api.js
const mockLog = [
  {
    battleTime: new Date().toISOString(),
    result: 'victory',
    brawler: 'Shelly',
    mode: 'Gem Grab'
  },
  {
    battleTime: new Date(Date.now() - 60000).toISOString(),
    result: 'defeat',
    brawler: 'Colt',
    mode: 'Showdown'
  }
];

async function getBattleLog(tag) {
  // Simulate an API call delay
  await new Promise((r) => setTimeout(r, 500));
  return mockLog;
}

module.exports = { getBattleLog };
Enter fullscreen mode Exit fullscreen mode

Step 3: Store Battle Logs with LowDB

In db.js:

const { Low, JSONFile } = require('lowdb');
const path = require('path');

const file = path.join(__dirname, 'db.json');
const adapter = new JSONFile(file);
const db = new Low(adapter);

async function initDB() {
  await db.read();
  db.data ||= { logs: [] };
  await db.write();
}

async function saveBattleLog(entries) {
  await initDB();
  const existing = db.data.logs.map((e) => e.battleTime);
  const newEntries = entries.filter((e) => !existing.includes(e.battleTime));
  db.data.logs.push(...newEntries);
  await db.write();
}

async function getAllLogs() {
  await initDB();
  return db.data.logs;
}

module.exports = { saveBattleLog, getAllLogs };
Enter fullscreen mode Exit fullscreen mode

Step 4: Build the Express Server

Now let’s glue it together in server.js:

require('dotenv').config();
const express = require('express');
const cron = require('node-cron');
const { getBattleLog } = require('./api');
const { saveBattleLog, getAllLogs } = require('./db');

const app = express();
const port = 3000;

app.use(express.json());

// API route to fetch battle logs manually
app.get('/logs', async (req, res) => {
  const logs = await getAllLogs();
  res.json(logs);
});

// Get most used brawler
app.get('/top-brawler', async (req, res) => {
  const logs = await getAllLogs();
  const counts = {};

  logs.forEach(({ brawler }) => {
    counts[brawler] = (counts[brawler] || 0) + 1;
  });

  const sorted = Object.entries(counts).sort((a, b) => b[1] - a[1]);
  const [top, freq] = sorted[0] || ['None', 0];

  res.json({ topBrawler: top, timesUsed: freq });
});
Enter fullscreen mode Exit fullscreen mode

Step 5: Automate Battle Log Fetching

Inside server.js, add a cron job that runs every 10 minutes:

cron.schedule('*/10 * * * *', async () => {
  const logs = await getBattleLog(process.env.PLAYER_TAG);
  await saveBattleLog(logs);
  console.log(`[BOT] Synced ${logs.length} battle logs at ${new Date().toISOString()}`);
});

app.listen(port, () => {
  console.log(`🎮 Null's Brawl Tracker Bot running at http://localhost:${port}`);
});
Enter fullscreen mode Exit fullscreen mode

Bonus: Get Win Rate

Let’s add one more API to calculate win rate:

app.get('/winrate', async (req, res) => {
  const logs = await getAllLogs();
  const total = logs.length;
  const wins = logs.filter(l => l.result === 'victory').length;

  res.json({
    totalGames: total,
    wins,
    losses: total - wins,
    winRate: total ? ((wins / total) * 100).toFixed(2) + '%' : '0%'
  });
});

Enter fullscreen mode Exit fullscreen mode

Test Everything

Start your bot:

node server.js
Enter fullscreen mode Exit fullscreen mode

Then hit the endpoints:

  • /logs → See your synced battles
  • /top-brawler → Find your most used brawler
  • /winrate → Win/loss ratio

Next Steps: Go Bigger

Once your local tracker works, here’s what you could build next:

  • A dashboard with Chart.js or React
  • Store logs in a proper DB (like MongoDB)
  • Analyze mode-based performance (e.g., Gem Grab vs Showdown)
  • Add a CLI tool to run stats in terminal
  • Discord integration to post win rates

Final Thoughts

Null’s Brawl might not be official, but that doesn’t mean you can’t build real tools around it. With a little Node.js, some smart data tracking, and time, you can create your own analytics platform — even without an official API.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.