Advanced Examples
Three complete scenarios that combine network variables, signals, conditions, placeholders and the events section of the Paper config. For single features, start with the Common Examples.
These examples require MythicMobs Premium!
This page is divided into 3 examples:
Before You Start
- Read Before You Start on the Common Examples page. It explains where the files go, how the
eventslists work and how targeters behave in these skills. - All scenarios run on two servers,
lobbyandsurvival, behind one Velocity proxy, with MythicProxy on the proxy and on both servers (see Installation). - The mobs use
Despawn: PERSISTENT, so they are saved and come back after a restart. A mob in an unloaded chunk runs no timer skills and receives no signals, so keep the chunks of these mobs loaded.
Raid Titan
A boss on survival whose health shows on a name tag in the lobby, with damage totals per player, a network record and a kill announcement on every server.
In Mobs/raid_titan.yml on survival:
RaidTitan:
Type: IRON_GOLEM
Display: '&4Raid Titan'
Health: 1000
Options:
Despawn: PERSISTENT
AlwaysShowName: true
Skills:
- skill{s=RaidTitanSpawn} ~onSpawn
- skill{s=RaidTitanRecordDamage} @trigger ~onDamaged
- skill{s=RaidTitanPublishHp} ~onTimer:20
- skill{s=RaidTitanDeath} ~onDeath
In Mobs/raid_status_board.yml on lobby:
RaidStatusBoard:
Type: ARMOR_STAND
Display: '&4Raid Titan &7idle'
Options:
Despawn: PERSISTENT
AlwaysShowName: true
Skills:
- setname{n="&4Raid Titan &7idle"} ~onTimer:20 ?!networkVariableIsSet{var=raid_phase}
- setname{n="&4Raid Titan &c<global.netvar.raid_boss_hp|0>&7/&c<global.netvar.raid_boss_mhp|0> &7HP, top damage &e<global.netvar.raid_top_name|nobody> &c<global.netvar.raid_top_damage|0>"} ~onTimer:20 ?networkVariableEquals{var=raid_phase;value=active}
- setname{n="&4Raid Titan &aslain by <global.netvar.raid_killer|nobody>"} ~onTimer:20 ?networkVariableEquals{var=raid_phase;value=cleared}
In Skills/raid_titan.yml on survival:
RaidTitanSpawn:
Skills:
- networkVariableAdd{var=raid_id;amount=1}
- networkVariableSet{var=raid_phase;type=STRING;value=active}
- networkVariableSet{var=raid_boss_mhp;type=DOUBLE;value=<caster.mhp>}
- networkVariableSet{var=raid_boss_hp;type=DOUBLE;value=<caster.hp>;save=false}
- networkVariableUnset{var=raid_top_damage}
- networkVariableUnset{var=raid_top_name}
- networkVariableUnset{var=raid_killer}
- networkSignal{signal=raidstart;target=all;payload=<caster.name>}
RaidTitanRecordDamage:
TargetConditions:
- isplayer
Skills:
- skill{s=RaidTitanResetTotal}
- networkVariableSet{var=raid_seen;scope=target;type=INTEGER;value=<global.netvar.raid_id|0>}
- networkVariableAdd{var=raid_damage;scope=target;type=DOUBLE;amount=<skill.var.damage-amount>}
- skill{s=RaidTitanTrackTopDamage}
RaidTitanResetTotal:
TargetConditions:
- compareValues{val1=<target.netvar.raid_seen|0>;val2=<global.netvar.raid_id|0>;op=NE}
Skills:
- networkVariableSet{var=raid_damage;scope=target;type=DOUBLE;value=0}
RaidTitanTrackTopDamage:
TargetConditions:
- compareValues{val1=<target.netvar.raid_damage|0>;val2=<global.netvar.raid_top_damage|0>;op=GT}
Skills:
- networkVariableSet{var=raid_top_damage;type=DOUBLE;value=<target.netvar.raid_damage|0>}
- networkVariableSet{var=raid_top_name;type=STRING;value=<target.name>}
RaidTitanPublishHp:
Skills:
- networkVariableSet{var=raid_boss_hp;type=DOUBLE;value=<caster.hp>;save=false}
RaidTitanDeath:
Skills:
- networkVariableSet{var=raid_phase;type=STRING;value=cleared}
- networkVariableSet{var=raid_boss_hp;type=DOUBLE;value=0;save=false}
- networkVariableSet{var=raid_killer;type=STRING;value=<trigger.name>} ?~isplayer
- networkVariableAdd{var=raid_kills;scope=target;amount=1} ?~isplayer
- networkSignal{signal=raidkill;target=all}
- networkSignal{signal=raidkillerreward} ?~isplayer
In Skills/raid_network.yml on both servers:
RaidStartAnnounce:
Skills:
- message{m="&4<skill.var.signal-payload> &7has risen on &e<skill.var.origin-server>&7. Players there now<&co> &e<network.server.survival.online>"} @self
RaidKillAnnounce:
Skills:
- message{m="&6<global.netvar.raid_killer|nobody> &7slew the Raid Titan on &e<skill.var.origin-server>&7. Top damage<&co> &c<global.netvar.raid_top_damage|0> &7by &e<global.netvar.raid_top_name|nobody>"} @self
RaidKillerReward:
Skills:
- message{m="&6You landed the killing blow on the Raid Titan. Your damage this raid<&co> &c<caster.netvar.raid_damage|0>&6, lifetime titan kills<&co> &c<caster.netvar.raid_kills|1>"} @self
RaidJoinReport:
Conditions:
- networkVariableIsSet{var=raid_phase}
Skills:
- message{m="&7Raid Titan status<&co> &e<global.netvar.raid_phase|idle>&7. You have not damaged this titan yet."} @self ?compareValues{val1=<caster.netvar.raid_seen|0>;val2=<global.netvar.raid_id|0>;op=NE}
- message{m="&7Raid Titan status<&co> &e<global.netvar.raid_phase|idle>&7. Your damage<&co> &c<caster.netvar.raid_damage|0>&7, top damage<&co> &c<global.netvar.raid_top_damage|0> &7by &e<global.netvar.raid_top_name|nobody>"} @self ?compareValues{val1=<caster.netvar.raid_seen|0>;val2=<global.netvar.raid_id|0>;op=EQ}
- message{m="&aYou hold the top damage record."} @self ?compareValues{val1=<caster.netvar.raid_seen|0>;val2=<global.netvar.raid_id|0>;op=EQ} ?compareValues{val1=<caster.netvar.raid_damage|0>;val2=<global.netvar.raid_top_damage|0>;op=GTE}
RaidReset:
Skills:
- networkVariableUnset{var=raid_phase}
- networkVariableUnset{var=raid_boss_hp}
- networkVariableUnset{var=raid_boss_mhp}
- networkVariableUnset{var=raid_top_damage}
- networkVariableUnset{var=raid_top_name}
- networkVariableUnset{var=raid_killer}
In config.yml on both servers:
events:
network-join:
- RaidJoinReport
server-switch:
- RaidJoinReport
network-quit: []
signal:
raidstart:
- RaidStartAnnounce
raidkill:
- RaidKillAnnounce
raidkillerreward:
- RaidKillerReward
How It Works
raid_boss_hpusessave=false, so a server that connects later never receives an old health value.raid_seenholds theraid_idof the titan a player last hit. On a player's first hit against a new titan,RaidTitanResetTotalsets their old total back to 0.- The death lines have no targeter, so they act on the killer in any game mode, and
networkSignalwithouttarget=goes to the killer alone. With@trigger, a killer in creative mode would be skipped andraidkillerrewardwould go to every player. /mm test cast RaidResetsets the board back to idle. The totals per player stay until the first hit against the next titan.
Wanted
Killing a merchant makes the killer wanted on every server for ten minutes. Guards everywhere hunt wanted players, a clerk reports the wanted level and a fine collector clears it.
In Mobs/wanted.yml on every server:
TownMerchant:
Type: VILLAGER
Display: '&aTown Merchant'
Health: 20
Options:
Despawn: PERSISTENT
Skills:
- skill{s=OutlawKill} @trigger ~onDeath ?~isplayer
TownGuard:
Type: IRON_GOLEM
Display: '&7Town Guard'
Health: 80
Damage: 6
Modules:
ThreatTable: true
Options:
Despawn: PERSISTENT
Skills:
- skill{s=GuardScan} @PlayersInRadius{r=12} ~onTimer:40
- skill{s=GuardOutlawShout} ~onNetworkSignal ?stringEquals{val1=<skill.var.signal>;val2=outlaw}
BountyClerk:
Type: VILLAGER
Display: '&6Bounty Clerk'
Options:
Despawn: PERSISTENT
Skills:
- skill{s=BountyCheck} @trigger ~onInteract
FineCollector:
Type: VILLAGER
Display: '&eFine Collector'
Options:
Despawn: PERSISTENT
Skills:
- skill{s=PayFine} @trigger ~onInteract
In Skills/wanted.yml on every server:
OutlawKill:
Skills:
- networkVariableAdd{var=wanted;scope=target;amount=1;duration=12000}
- message{m="&cYou murdered a merchant. Wanted level<&co> &4<target.netvar.wanted|1>&c. It fades ten minutes after your last crime."}
- networkSignal{signal=outlaw;target=all;payload=<trigger.name>}
GuardScan:
TargetConditions:
- networkVariableInRange{var=wanted;scope=target;min=1}
Skills:
- threat{mode=add;amount=100}
GuardOutlawShout:
Skills:
- message{m="&7[Guard] &f<skill.var.signal-payload> &7is wanted for murder on &e<skill.var.origin-server>&7. Stay sharp."} @PlayersInRadius{r=20}
BountyCheck:
Skills:
- message{m="&6[Bounty Clerk] &7Your wanted level is &c<target.netvar.wanted|0>&7."} ?~networkVariableIsSet{var=wanted;scope=target}
- message{m="&6[Bounty Clerk] &7Your record is clean."} ?~!networkVariableIsSet{var=wanted;scope=target}
PayFine:
Skills:
- message{m="&e[Fine Collector] &7You have no outstanding fines."} ?~!networkVariableIsSet{var=wanted;scope=target}
- message{m="&e[Fine Collector] &7Fine paid. Your record is clean on every server."} ?~networkVariableIsSet{var=wanted;scope=target}
- networkVariableUnset{var=wanted;scope=target} ?~networkVariableIsSet{var=wanted;scope=target}
OutlawNotice:
Skills:
- message{m="&4[Wanted] &c<skill.var.signal-payload> &7murdered a merchant on &e<skill.var.origin-server>&7. Guards everywhere are on alert."} @self
In config.yml on every server:
events:
network-join: []
server-switch: []
network-quit: []
signal:
outlaw:
- OutlawNotice
How It Works
?~isplayeron the merchant's death line makes only kills by players count.duration=12000is ten minutes in ticks, and every new murder starts the ten minutes again.?stringEqualsmakes the guards react only to theoutlawsignal, see onNetworkSignal.
Letter Quest and Invasion
A quest stage per player that NPCs on two servers read and advance, reminders on join and switch, and an invisible coordinator in the lobby that starts an invasion on survival on a timer.
In Mobs/quest_lobby.yml on lobby:
QuestGuide:
Type: VILLAGER
Display: '&eQuest Guide'
Options:
Despawn: PERSISTENT
Skills:
- skill{s=QuestGuideTalk} @trigger ~onInteract
EventCoordinator:
Type: ARMOR_STAND
Display: 'Event Coordinator'
Options:
Despawn: PERSISTENT
Invisible: true
Skills:
- skill{s=EventCoordinatorTick} ~onTimer:1200
In Mobs/quest_survival.yml on survival:
QuestWarden:
Type: VILLAGER
Display: '&cWarden'
Options:
Despawn: PERSISTENT
Skills:
- skill{s=QuestWardenTalk} @trigger ~onInteract
InvasionSpawner:
Type: ARMOR_STAND
Display: 'Invasion Spawner'
Options:
Despawn: PERSISTENT
Invisible: true
Skills:
- skill{s=InvasionSpawn} ~onNetworkSignal ?stringEquals{val1=<skill.var.signal>;val2=invasion}
InvasionZombie:
Type: ZOMBIE
Display: '&4Invader'
Health: 40
In Skills/quest.yml on both servers:
QuestGuideTalk:
Skills:
- networkVariableSet{var=quest_stage;scope=target;value=1} ?~!networkVariableIsSet{var=quest_stage;scope=target}
- message{m="&eGuide<&co> &7Take my letter to the Warden on the survival server."} ?~networkVariableEquals{var=quest_stage;scope=target;value=1}
- message{m="&eGuide<&co> &7You already delivered my letter. Thank you."} ?~networkVariableEquals{var=quest_stage;scope=target;value=2}
QuestWardenTalk:
Skills:
- message{m="&cWarden<&co> &7No letter. Speak to the Guide in the lobby first."} ?~!networkVariableIsSet{var=quest_stage;scope=target}
- message{m="&cWarden<&co> &7Nothing more for you, <target.name>."} ?~networkVariableEquals{var=quest_stage;scope=target;value=2}
- skill{s=QuestWardenComplete} ?~networkVariableEquals{var=quest_stage;scope=target;value=1}
QuestWardenComplete:
Skills:
- networkVariableSet{var=quest_stage;scope=target;value=2}
- command{c="give <target.name> diamond 3"}
- message{m="&cWarden<&co> &7The Guide's letter at last. Take these, <target.name>."}
QuestObjectiveReminder:
Skills:
- message{m="&7You are on &e<skill.var.server>&7. Objective<&co> talk to the Guide in the lobby."} @self ?!networkVariableIsSet{var=quest_stage;scope=caster}
- message{m="&7You are on &e<skill.var.server>&7. Objective<&co> deliver the letter to the Warden on survival."} @self ?networkVariableEquals{var=quest_stage;scope=caster;value=1}
- message{m="&7You are on &e<skill.var.server>&7. Quest complete. Next invasion on survival in &e<global.netvar.event_minutes|unknown> &7minutes."} @self ?networkVariableEquals{var=quest_stage;scope=caster;value=2}
In Skills/invasion.yml on both servers:
EventCoordinatorTick:
Skills:
- networkVariableAdd{var=event_minutes;amount=-1} ?networkVariableInRange{var=event_minutes;min=1}
- skill{s=EventInvasionLaunch} ?networkVariableInRange{var=event_minutes;min=0;max=0}
- networkVariableSet{var=event_minutes;value=10} ?!networkVariableIsSet{var=event_minutes}
EventInvasionLaunch:
Skills:
- networkSignal{signal=invasion;target=server:survival;payload=<network.server.survival.online>} ?compareValues{val1=<network.server.survival.online>;val2=2;op=GTE}
- networkVariableSet{var=event_minutes;value=10}
InvasionWarning:
Skills:
- message{m="&4The invasion begins. &7Called from &e<skill.var.origin-server>&7."} @self
In Skills/invasion_survival.yml on survival only, because InvasionZombie exists only there:
InvasionSpawn:
Skills:
- summon{type=InvasionZombie;amount=8;radius=6} @self
- message{m="&4Invasion. &7<skill.var.signal-payload> defenders online, eight invaders at the spawner."} @PlayersInRadius{r=60}
In config.yml on both servers:
events:
network-join:
- QuestObjectiveReminder
server-switch:
- QuestObjectiveReminder
network-quit: []
signal:
invasion:
- InvasionWarning
How It Works
EventCoordinatorTickruns every minute (1200 ticks). The first run setsevent_minutesto 10 and each later run subtracts 1. When it reaches 0,EventInvasionLaunchsignalssurvivalif at least two players are online there, and sets the countdown back to 10 either way.target=server:survivalsends the signal tosurvivalonly, see Target Attribute.- Spawn only one coordinator on the network. It is the only writer of
event_minutes, and two would count down twice as fast.
Using the Examples Together
The examples share no names, so you can run all three. With all three, the events section on each server reads:
events:
network-join:
- RaidJoinReport
- QuestObjectiveReminder
server-switch:
- RaidJoinReport
- QuestObjectiveReminder
network-quit: []
signal:
raidstart:
- RaidStartAnnounce
raidkill:
- RaidKillAnnounce
raidkillerreward:
- RaidKillerReward
outlaw:
- OutlawNotice
invasion:
- InvasionWarning