Skálamon is a faithful clone of the classic Pokémon battle system. It features a turn-based strategic combat mechanic between two teams of Pokémon (or rather Skálamon), each controlled by a trainer.
- Enjoy intense offline battles between Skalámon creatures with your friends
- Battle logic faithfully inspired by the original game mechanics
- Create your own Skalámon generation using a fluent and expressive DSL
- Minimalist GUI that keeps the focus on your strategy
- Turn-based system designed for competitive and casual play
- Quick to set up — just download, launch, and start battling
Download the latest JAR file from the GitHub releases page.
Run the JAR:
java -jar Skalamon.jarthen you and your friend can create your own teams and join the battle.
At the start of the battle, you and your opponent will receive a dictionary that maps each letter of the alphabet to a specific Pokémon. Each player must enter their nickname and select their team by typing the letters corresponding to the chosen Pokémon in the terminal.
Alternatively, to jump straight into the game without manually selecting a team, you can type skip during the team selection phase to receive a default team automatically.
Player 1
- Moves are assigned to buttons: Q - W - E - R
- Skalámon Team members are assigned to buttons: 1 - 2 - 3 - 4 - 5 - 6
Player 2
- Moves are assigned to buttons: Z - X - C - V
- Skalámon Team members are assigned to buttons: A - S - D - F - G
One action per turn per player: if a move is executed, switching is not allowed — and vice versa.
The turn automatically progresses once both players have made their choices.
Easy way to create your Skalámon using a fluent DSL
Customize the following attributes:
- Name – Give your Skálamon a unique name
- Types – Specify one or more elemental types
- Max HP – Define its maximum health points
- Weight – Set its weight
- Ability – Set its weight
- Statistics – Define its default statistics:
- Attack
- Defense
- Special Attack
- Special Defense
- Speed
- Moves set – Assign one to four moves
def pikachu: Pokemon =
pokemon("Pikachu"):
_ typed Electric hp 35 weighing 6.0.kg ability static stat Attack -> 55 stat Defense -> 40 stat SpecialAttack -> 50 stat SpecialDefense -> 50 stat Speed -> 90 moves (
tackle,
quickAttack,
thunderbolt,
thunderWave
)def bulbasaur: Pokemon =
pokemon("Bulbasaur"):
_ typed Grass + Poison hp 45 weighing 6.9.kg ability naturalCure stat Attack -> 49 stat Defense -> 49 stat SpecialAttack -> 65 stat SpecialDefense -> 65 stat Speed -> 45 moves(
tackle,
grassKnot,
razorLeaf,
bulletSeed
)Creating your Skalámon moves is just as easy. You can customize:
- Name – The move’s name
- Priority – The move’s execution priority
- Type – Choose one elemental type
- Category – One of: Physical, Special, or Status
- Accuracy – The chance to hit
- Power Points (PP) – Number of times the move can be used
- Success Behavior – Effects that trigger on success (can be combined)
- Failure Behavior – Effects that trigger on failure (can be combined)
def quickAttack: Move =
move("Quick Attack", Normal, Physical):
_ pp 30 priority 1 onSuccess SingleHitBehavior(40)def dragonDance: Move =
move("Dragon Dance", Dragon, Status):
_ pp 20 onSuccess new BehaviorGroup(
StatChangeBehavior(Attack + 1),
StatChangeBehavior(Speed + 1)
) with TargetModifier(Self)Create your abilities by customizing:
- Name – The name of the ability
- Hooks – A list of behaviors triggered by specific game events
def sandStream: Ability =
ability("Sand Stream"):
_.on(ActionEvents.Switch): (source, _, switch) =>
if switch.in is source then
WeatherBehavior(Sandstorm(_))
else
nothingYou can freely create custom field effects using a mixin-based system, allowing you to compose only the features you need:
- Name and description – Define the field effect’s name and provide a short explanation of what it does.
- Type modifiers – Modify move damage based on move types, influencing battle dynamics.
- Hooks – React to in-battle events applying changes on Skalámon in field.
- Expirable – Make the effect temporary for a fixed duration.
- BattleRule – Customize battle rules while the effect is active (e.g. moves order).
case class TrickRoom(t: Int) extends Room with FieldEffect(t)
with Expirable(t, TrickRoom.Duration) with MutatedBattleRule:
override val name: String = TrickRoom.Name
override val description: String = TrickRoom.Description
override val rule: BattleRule = Tricky()case class Sunny(t: Int)
extends Weather
with FieldEffect(t)
with TypesModifier
with Expirable(t, Sunny.Duration):
override val name: String = Sunny.Name
override val typesModifier: Map[Type, Double] =
Map(Fire -> Sunny.FireModifier, Water -> Sunny.WaterModifier)
override val description: String = Sunny.Descriptioncase class Sandstorm(t: Int)
extends Weather
with FieldEffect(t)
with Hooks
with Expirable(t, Sandstorm.Duration):
override val name: String = Sandstorm.Name
override val description: String = Sandstorm.Description
override val hooks: List[(EventType[_], PokemonRule)] =
(
Started,
Modify.except(Rock, Steel, Ground) { p =>
p.copy(currentHP = p.currentHP - Sandstorm.Damange)
}
) :: Nil