Lua Scripting in Final Fantasy XI

Yes, that FFXI, the one that came out in 2003

Why talk about this?

  • This game is 17 years old
  • I just find the history and progression of how the game and community evolved utterly fascinating
  • FFXI is a beautiful mess of a game
    • don't actually play it
    • stare at it like you'd stare at a car crash, transfixed by the rising flames and smoke
  • In hindsight it seems like it's this collaborative game design/development process between devs and players

this game was made in 2003 why am i talking about this

Disclaimer:

  • None of this is allowed in the EULA
  • For various reasons, Square Enix turns a blind eye to innocuous uses of scripting
    • Botting will get you banned
    • Position hacking will get you banned
    • This talk isn't about any of that

3rd party support

  • Game came out on PS2 and PC in 2002 (Japan) and 2003 (US)
    • A lot of issues stem from its PS2 DNA
  • PC version would not let you alt-tab or resize the game window
  • People made a wrapper to put the client in to allow for this basic functionality
    • This wrapper program was known as Windower
  • Later versions of Windower allowed for addon support
    • Initially written in C and compiled to .dlls
    • Most recent version implemented Lua scripting

This game is still running

  • It's difficult for the official dev team to allocate resources to update the game's client
    • at least up to recently, they need PS2 dev kits to build both client and server, and there are like six of those left in the world that work
  • It's easy for players to modify the client
  • SE has recognized this and lets most of it slide

tyler none of this has been lua yet

  • i'm getting there

GearSwap

  • GearSwap is a lua-based addon for Windower 4
  • You can define sets of gear and under what conditions you'll automatically swap to that gear
  • This is a vital part of FFXI

Horizontal Progression

  • FFXI's progression system isn't entirely vertical
  • Other games typically make upgrades easy to reason about
    • WoW's gear score
    • FFXIV's item level
    • etc. bigger stats = better

Horizontal Progression

  • Most other games don't let you change gear mid-fight
  • FFXI ... does, and the design accounts for it
    • There's an in-game macro system!
    • very limited though, few lines

Equipment slots

 

16 slots for equipment

 

In-game macro system has six lines, maximum

 

Can only change five pieces of gear at once without spilling into other macros

Horizontal progression

  • Pieces of gear have niche uses
  • Progression is about how wide your armory is, not how strong your strongest sword is
  • You don't need to choose between which of these to wear!
  • But you do need to juggle them with macros or gearswap

finally an example

  • GearSwap reads incoming and outgoing packets
    • Define sets at the start of the file
    • Ability use has three phases:
      • precast
      • midcast
      • aftercast
        • because FFXI checks different parameters at different times of ability use

Some sets

sets.Idle =
{
	ammo="Staunch tathlum"
	head="Rawhide mask",
	neck="Sanctity necklace",
	ear1="Ethereal earring",
	ear2="Brachyura earring",
	body="Jhakri robe +2",
	hands="Herculean gloves",
	ring1="Karieyh ring",
	ring2="Defending ring",
	back="Rosmerta's cape",
	waist="Flume belt",
	legs="Carmine cuisses +1",
	feet="Ayanmo gambieras +2"
}
sets.TP =
{
	ammo="Ginsen"
	head="Adhemar bonnet +1",
	neck="Mirage stole +1",
	ear1="Suppanomimi",
	ear2="Cessance earring",
	body="Adhemar jacket +1",
	hands="Adhemar wristbands +1",
	ring1="Epona's ring",
	ring2="Petrov ring",
	back="Rosmerta's cape",
	waist="Windbuffet belt +1",
	legs="Samnuha tights",
	feet="Herculean boots"
}
sets.ChantDuCygne =
{
	ammo="Jukukik feather"
	head="Adhemar bonnet +1",
	neck="Mirage stole +1",
	ear1="Moonshade earring",
	ear2="Brutal earring",
	body="Ayanmo corazza +2",
	hands="Adhemar wristbands +1",
	ring1="Epona's ring",
	ring2="Begrudging ring",
	back="Rosmerta's cape",
	waist="Fotia belt",
	legs="Samnuha tights",
	feet="Herculean boots"
}

Function hooks

  • Now with sets defined, override the precast, midcast, and aftercast hooks
function precast(spell)
	if spell.english == 'Chant du Cygne' then
		equip(sets.ChantDuCygne)
	end
end

function midcast(spell)

end

function aftercast(spell)
	if player.status == 'Engaged' then
		equip(sets.TP)
	else
		equip(sets.Idle)
	end
end

well that doesn't seem so bad

  • just map some equipment to abilities and you're good to go right?
    • weeeeeell it's not always that easy

how was anyone supposed to use the macro system to juggle any of this

  • Left: a piece of gear known as the "weather belt"
  • Right: a generically good piece of gear for casting spells in

Let's talk about the weather

  • There are eight weather effects in the game
  • Each of them correspond to one of eight elements
  • If you cast a spell that matches the element of the current weather, there is a 1/3 chance for the spell to be upgraded in power
    • 10% power upgrade for one icon, 25% for two

this belt

  • this belt, if matching weather is active, beats the pants off of anything else in that slot
    • It forces the 1/3 chance for a weather proc to occur 100% of the time.
  • if matching weather is not active, it's completely useless

Conditionals

  • one of the big draws of gearswap is to handle special cases like this and add conditional logic
    • macro system has nothing like this
  • Assume we have a general black magic midcast set, and in our midcast function hook, we do this:
if world.weather_element == spell.element then
	equip( set_combine( sets.BlackMagicMidcast, { waist="Hachirin-no-Obi" } ) )
end

Now, all we have to think about is just when to use our abilities, and it'll automatically swap out the belt only when it's relevant

in conclusion

  • don't actually play FFXI unless you're in for doing a lot of programming yourself to make the game even functional or fun
  • maybe that's your thing! i mean, it's mine
  • i have no idea if this made sense to anyone

Lua scripting in Final Fantasy XI

By tdhoward

Lua scripting in Final Fantasy XI

  • 470