Bagmon League docs
Types, eggs, merges, lands, the pit and the engine that swings every bag. Every number on this page is read from lib/bagmon.js, the same file the game runs on.
01Introduction
Bagmon League is a pixel monster league where the monsters are bags. You hatch them from eggs, merge three of the same into a heavier one, park the spares on lands to farm $BAGMON, and send your best six into the pit for 6v6 fights.
You never press attack. You pick the six, set a plan and an order, and the engine plays every hit. The engine is one open file, so any fight can be replayed hit for hit from its seed.
What is on the site
- The main page with a live fight that never stops.
- The demo: eggs, bags, lands and the eight-rung ladder, saved in your browser.
- These docs, and the engine itself at
/lib/bagmon.js.
02Quick start
- Open the demo and pick your first bag: Gemlet, Apelet or Krillet.
- Hatch the four free eggs. Every hatch shows its rarity roll.
- Open Bags. When you have three of the same kind and stage, merge them.
- Put the bags you are not fighting with on Lands. Claim before they fill.
- Open The Pit, press Auto-pick six, choose a plan and fight Intern Ivy.
03How a season works
A season is one ladder of eight rivals. Each rung sends a bigger and heavier six than the last: rung 1 brings three bags, rung 4 and up bring a full six, and the last two rungs field stage 3 bags.
The loop
Fight → win $BAGMON → buy eggs → merge → fight the next rung. Lands keep paying while you are away, so the loop does not stop when you close the tab.
04Types and the ring
There are eight types, set in a ring. Each type deals ×1.5 to the next one around the ring and ×0.67 to the one before it. Everything else is ×1.
| Type | Beats | Loses to | Why |
|---|
05The 24 bags
Every type has one line of three stages. Base stats are HP, attack, defence and speed before stage, level and rarity.
| Stage 1 | Stage 2 | Stage 3 | Base HP/ATK/DEF/SPD | Moves |
|---|
06Rarity and Shiny
Rarity multiplies battle stats and farm rate. Shiny is cosmetic: a recoloured bag with the same stats.
| Rarity | Stats | Farm | Basic egg | Golden egg |
|---|
Shiny odds are 1 in 64 on every egg, rolled separately from rarity.
07Eggs and odds
An egg rolls three numbers in order: rarity (0–100), Shiny (0–1) and type (one of eight, equal odds). The first two are returned with the bag as rolls, so a hatch can be checked against the table above.
| Egg | Price | Never hatches |
|---|---|---|
| Basic Egg | 2,000 $BAGMON | — |
| Golden Egg | 8,000 $BAGMON | Common |
const bag = Bagmon.hatch('golden', 1234); // { type: 'burn', stage: 1, rarity: 1, shiny: false, rolls: { rarity: 7.329, shiny: 0.7034 } } console.log(Bagmon.name(bag), Bagmon.RARITY[bag.rarity].name); // Emberlet Uncommon
<script src="https://bagmonleague.vercel.app/lib/bagmon.js"></script> <script> const bag = Bagmon.hatch('basic'); document.body.textContent = Bagmon.name(bag); </script>
08Merging
Three bags of the same type and the same stage merge into one bag of the next stage. Stage 3 is the top. The new bag keeps the best rarity of the three, and it is Shiny if any of the three was.
const a = Bagmon.make('diamond', 1, 0), b = Bagmon.make('diamond', 1, 2), c = Bagmon.make('diamond', 1, 1); Bagmon.canMerge(a, b, c); // true const up = Bagmon.merge(a, b, c); // Glintsack, rarity 2 (Rare)
09Lands and farming
Each land holds three bags. A bag farms 120 × stage × rarity $BAGMON an hour, where stage counts as 1, 2.5 or 5. A bag on a land of its own type farms ×1.5. When a land reaches its cap it stops until you claim.
| Land | Type | Cap | Three matching Rare stage 2 fill it in |
|---|
Short lands like the Paper Mill suit people who check in all day. Deep ones like the Deep Pool suit one claim before bed.
10The pit
The pit is a ladder of eight rivals. Rival teams come from Bagmon.rival(rung), so everyone faces the same six on the same rung.
| Rung | Rival | Their bags | Pays |
|---|
11Plans and order
| Plan | Attack | Defence | Strong move |
|---|---|---|---|
| Aggressive | ×1.2 | ×0.85 | Every time it is ready |
| Balanced | ×1 | ×1 | When the target has more than 30% HP |
| Defensive | ×0.9 | ×1.25 | When the target has more than 60% HP |
Any plan fires the strong move when its own bag drops under 35% HP. A strong move has a three-turn cooldown.
Order
In order sends your six as listed. By type picks, every time a bag goes down, the remaining bag with the best type matchup against the rival's current bag.
12How a fight is computed
Each turn the faster bag acts first (a speed tie is a coin flip). The attacker picks its move by plan, then damage is:
dmg = floor(((2 × lv / 5 + 2) × power × (atk × planAtk) / (def × planDef)) / 14 + 2) dmg = round(dmg × type × (crit ? 1.5 : 1) × random(0.85 … 1.0)) // at least 1 // type: 1.5 strong, 0.67 weak, 1 otherwise · crit: 1 in 16
When a bag hits 0 HP it is out and the next one comes in. The fight ends when one side has no bags left. A fight that runs past 400 turns is a draw.
Seeds
All randomness comes from a seeded generator (mulberry32). Same teams, plans and seed give the same fight, hit for hit.
13bagmon.js
The engine is a single script with no dependencies. Load it from the site and it sets window.Bagmon. In Node it exports the same object.
<script src="https://bagmonleague.vercel.app/lib/bagmon.js"></script> <script> const mine = [Bagmon.make('diamond', 2, 1), Bagmon.make('bot', 1, 0)]; const fight = Bagmon.battle(mine, Bagmon.rival(0), { seed: 42, plan: 'aggressive' }); console.log(fight.winner === 0 ? 'won' : 'lost', fight.left); </script>
# save the file next to your script curl -O https://bagmonleague.vercel.app/lib/bagmon.js node -e "const B=require('./bagmon.js'); console.log(B.battle([B.make('whale',2)],B.rival(0),{seed:7}).winner)"
| Function | Returns |
|---|---|
make(type, stage, rarity, shiny) | A new bag object. |
hatch(egg, seed?) | A bag with rolls. Egg is 'basic' or 'golden'. |
canMerge(a, b, c) · merge(a, b, c) | Boolean · the next-stage bag. |
stats(bag) | {hp, atk, def, spd, lv, ovr} |
multiplier(attacker, defender) | 1.5, 1 or 0.67. |
farmRate(bag, land?) · farm(land, bags, hours) | Per hour · {perHour, stored, full, hoursToFull} |
battle(teamA, teamB, opts) | {winner, left, events}. Opts: seed, plan, order, rivalPlan, rivalOrder. |
rival(rung) | The rival team for a rung, 0–7. |
name(bag) · rng(seed) | Species name · a seeded random function. |
14Try it
This box runs the real engine and replays the result with lib/arena.js.
Your team:
Press Run.
15Event format
battle() returns every step as an event. A screen replays them in order.
| t | Fields | Meaning |
|---|---|---|
in | side, bag | A bag enters. Side 0 is you, 1 is the rival. |
hit | side, move, strong, dmg, mult, crit, hp, max | The bag on side hits. hp is what the target has left. |
ko | side, bag | The bag on side is out. |
end | winner, left, draw? | Fight over. left is bags standing on each side. |
16pixel.js sprites
No bag on the site is an image file. lib/pixel.js builds each one on a 32×32 grid: body, knot, face, the type's mark, shading and a one-pixel outline, then returns a canvas.
const cv = Pixel.bag('burn', 3, { scale: 4, shiny: true }); // a 128×128 Shiny Pyrebag document.body.append(cv); Pixel.egg('golden', 4); Pixel.trainer(7, 0, 3);
17Constants
| Name | Value |
|---|
18Errors
| Where | Message | Fix |
|---|---|---|
merge() | Merge needs three bags of the same type and stage, below stage 3. | Check with canMerge() first. |
| Demo · eggs | Not enough $BAGMON. Claim your lands first. | Claim, or win a rung. |
| Demo · pit | Put at least one bag in your six. | Use Auto-pick six. |
19Limits
- The demo saves to
localStorage. Clearing site data or another browser starts you over. - Rivals are fixed per rung. Knowing the ladder is part of the game.
- Seeds are 32-bit. Two different seeds can, rarely, give the same fight.
20$BAGMON
$BAGMON is the coin of the league and its Solana token. Eggs cost it, lands farm it and the pit pays it.
21FAQ
Why can't I attack myself?
Because the fun part is the build. Pick the six, set the plan and the order, then watch it go.
Is a rival ever random?
No. rival(rung) always returns the same six. Only the fight's seed changes between tries.
Can I check a fight someone posts?
Yes. Ask for their six, their plan and the seed, then run it in Try it or in Node.
Is it risky?
It is a crypto token and the price moves both ways. Only put in what you are fine losing.