Skip to content

Instantly share code, notes, and snippets.

@cfjedimaster
Created June 18, 2026 19:36
Show Gist options
  • Select an option

  • Save cfjedimaster/7012161cd54605ee9d96516547d92b9d to your computer and use it in GitHub Desktop.

Select an option

Save cfjedimaster/7012161cd54605ee9d96516547d92b9d to your computer and use it in GitHub Desktop.
summary.md

My Little Mortal Combat — Mechanics Report

My Little Mortal Combat (MLMC) is a browser-based single-player arena fighter. It blends My Little Pony flavor with rock-paper-scissors combat and light RPG progression. The stack is vanilla HTML/CSS plus Alpine.js, with game state saved to localStorage.


Overview

Aspect Detail
Genre Turn-based RPS fighter + RPG progression
Platform Static web app (no backend)
Save system One slot in localStorage (pcPony)
Tagline "Friendship is fatal"

The game loop is: name your pony → train skills → pick an opponent → fight → earn gold/XP → repeat.


Game Flow (Three Views)

  1. Intro — Create a pony (name required) or load a saved game.
  2. Main (Arena) — View stats, train skills, choose 1 of 3 opponents, start a fight.
  3. Battle — Turn-based RPS until one side reaches 0 HP.

There is no path back to the intro screen after entering the arena.

Intro (name / continue)
    ↓
Arena Dashboard (train + pick foe)
    ↓
Battle (RPS rounds)
    ↓
Result dialog → back to Arena

Player Character

Each pony tracks:

Stat Starting value Notes
HP 50 Scales with level: level × 50
Attack / Defend / Vogue 1 each Trainable with gold
Gold 0 Earned from fights
XP 0 Same amount as gold earned; drives level

Level is derived from XP, not stored directly:

function xpToLevel(xp) {
  if (xp <= 0) return 1;
  return Math.floor(Math.pow(xp / 100, 1 / 1.5)) + 1;
}

Approximate level thresholds:

Level XP needed (approx.)
1 0
2 100
3 ~283
4 ~520
5 ~800

After each fight (win or lose), HP is fully restored to level × 50 before returning to the arena.


Combat System

Rock-Paper-Scissors Rules

The three moves form a cycle (shown in the battle UI):

Your move Beats Loses to
Attack Vogue Defend
Defend Attack Vogue
Vogue (Strike a Pose) Defend Attack
Same move Draw (no damage)

Turn Resolution

Each round:

  1. Player picks Attack, Defend, or Vogue.
  2. The NPC picks randomly (equal chance among all three).
  3. Outcome is resolved via the RPS table.
  4. Only the winner deals damage — draws deal none.

Damage Formula

let pcdmg = 10 * this.pcPony[type];
let npcdmg = 10 * this.selectedOpponent[npcMove];

Damage = 10 × skill level of the move used. Example: Attack 3 → 30 damage on a winning exchange.

Because the NPC move is random, higher skills help when you win, but do not change RPS outcomes.


Opponents

Three challengers are generated whenever you enter the arena or finish a fight.

Generation rules

let level = Math.max(1, this.level + getRandomIntInclusive(-1, 1))
let opp = {
  name: name + ' ' + getRandomArr(suffixes),
  level,
  currentHp: HP_PER_LEVEL * level,
  hp: HP_PER_LEVEL * level,
  hpPercentage: 100,
  bio,
  attack: Math.max(1, getRandomIntInclusive(level-2, level+2)),
  defend: Math.max(1, getRandomIntInclusive(level-2, level+2)),
  vogue: Math.max(1, getRandomIntInclusive(level-2, level+2)),
}
Property How it's set
Name Random MLP-style name + violent suffix (e.g. "Rainbow Dash the Mane Ripper")
Bio Three random passive-aggressive flavor lines
Level Player level ± 1 (minimum 1)
HP level × 50
Skills Each skill random in [level−2, level+2], minimum 1

Readme vs code mismatch (opponent level)

The readme says opponent level should be ±2 around the player level:

* ~~Make opponents have a level -2 to +2 around player level (min 1)~~

The code uses ±1 for level (line 70 in script.js):

/*
my level is -1 to +1 of my current level
*/
let level = Math.max(1, this.level + getRandomIntInclusive(-1, 1))

The -2 to +2 range on lines 78–80 applies to attack/defend/vogue stats, not opponent level. Either line 70 should be getRandomIntInclusive(-2, 2), or the readme is stale (the inline comment explicitly documents ±1).


Economy & Progression

Fight rewards

Outcome Gold & XP
Victory opponent.level × 100
Defeat 10% of that (floor(level × 10))

Gold and XP are always equal — the readme notes this may be tweaked later.

Training

train(skill) {
  if (this.pcPony.gold < this.pcPony[skill] * 10) {
    alert('Not enough gold to train!');
    return;
  }
  this.pcPony.gold -= this.pcPony[skill] * 10;
  this.pcPony[skill]++;
  this.persist();
}
Skill level Training cost
1 → 2 10 gold
2 → 3 20 gold
3 → 4 30 gold
n → n+1 n × 10 gold

Training is the main gold sink and the primary way to increase damage output.


Save System

  • Key: localStoragepcPony
  • When saved: After training and after each fight ends
  • Single slot: Starting a new game with an existing save prompts for confirmation
  • Continue: Intro shows saved pony name and level

The readme describes saves as "hackable as hell" — stats can be edited directly in browser dev tools.


Content & Flavor

  • Names (names.js): ~50 MLP character names
  • Suffixes (suffixes.js): Dark/violent titles ("the Dream Crusher", "Hoof Smasher", etc.)
  • Bios (bios.js): Humorous petty-evil traits ("double-dips at every dip", "replies 'k.' to paragraphs")

Bios are flavor only and do not affect combat.


Balance & Design Observations

Strengths

  • Simple, readable loop: fight → earn → train → fight harder opponents
  • RPS is easy to learn; random NPC moves add variance
  • Opponent scaling keeps fights relevant as you level
  • Full HP restore between fights avoids death-spiral attrition

Weaknesses / quirks

  1. No NPC intelligence — Pure random moves; no adaptation or level-based behavior
  2. Skill investment is one-dimensional — Training any skill helps only when that move wins
  3. XP = gold — No separate progression tuning
  4. Defeat still pays — 10% consolation reward reduces loss penalty
  5. Draws are common — ~33% of exchanges (when moves match); no damage, longer fights
  6. New game edge case — Starting fresh after a page load resets stats, but the flow doesn't explicitly reset pcPony if state was mutated in-session (minor; no return-to-intro path exists)

Planned Features (from readme)

The main outstanding item is Cutie Marks — not implemented yet. Core systems (XP, leveling, scaled opponents, damage formula, local save) are marked complete.


Summary

MLMC is a lightweight RPG arena game built around a three-move RPS system. Progression comes from gold-funded skill training and XP-driven leveling, which increases HP and opponent difficulty. Combat is deterministic given move choices, with randomness only from the NPC's move selection. The MLP parody theme (cute ponies, violent suffixes, passive-aggressive bios) is the main personality layer on top of straightforward mechanics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment