FFXIAH.com

Language: JP EN DE FR
New Items
2023-11-19
users online
GearSwap Tutorial Pt5

GearSwap Tutorial (v0.1)


PART 5



Abstractions


One of the keys to writing usable, understandable and maintainable code is understanding abstractions. Abstractions are ways of representing ideas as a whole, rather than the specifics of how an idea works.

A "farmer" is an abstraction. Just the word alone is enough to give you a rough idea of what a farmer does, what sorts of responsibilities he has, what sorts of things he works on, etc. Farmer driving a tractor? Yes. Farmer herding cows? Yes. Farmer in an Italian suit at a Wall Street business meeting? Not so much.

At the same time, when someone speaks to you about a farmer, they aren't going to give you a minute-by-minute detailing of every single thing he does over the course of the day. It's neither necessary nor relevant. "The farmer milked the cows" gives you all the information you probably need. You don't need to know the model of the milking machine he's using (or how much it cost, or what the current accounting depreciation schedule on it is), or how many cows, or when they were born, how to perform the homogenization process on the milk, or... Well, you get the point.

A coding abstraction is similar: it tells you just enough to know what belongs there, and what doesn't, and doesn't bog you down with all the details of how everything works.

The best way to build a program (which is what the lua script is) is to abstract as much as possible at each level. When a farmer tells his son to go milk the cows, he doesn't explain: how to stand up; how to get to the front door; how to unlock the door; how to find the path between the house and the barn; how to walk that path; how to open the barn door; how to identify and locate the cows; how to move the cows to the milking station; etc, etc etc, with tons more details left out. That's all abstracted away.

Functions in general are abstractions. They are the 'verbs' of the programming language. To as great an extent as possible, any time you want to 'do' something in your script, you should be able to do so by simply calling a function and giving it a few details.

A common programming adage is that no function should be more than 10 lines long (though that's more of a target than a real limit). The purpose of that concept is to minimize the amount of detail-work you put in each function, and simplify it to a few basic instructions (eg: go milk the cows).

Precast, midcast and aftercast are abstractions. In Spellcast, we had a single 'function' (the <rules> block) that defined everything that happened at any of the precast/midcast/aftercast points in time. It was long, laborious and messy.

In GearSwap we want to isolate things to smaller blocks of info. For example: What do I want to do before this spell is cast? Here's an example of how to simplify things.

Start:

If it's a spell, I want to put fast cast gear on, but if it's a weaponskill I want to use one of my weaponskill sets. Also, if it's Counterstance I need to put on Melee Gaiters, and if it's Focus I want to put on the Temple Crown, and if it's Chakra I need to make sure I'm wearing Temple Cyclas and Melee Gloves, plus as much vit gear as I have, etc....

Simplification 1:

If it's a spell, I want to put fast cast gear on. If it's a weaponskill or ability, I want to put on gear that will enhance that ability. [here's the list of weaponskills and JAs that I might use (...); for each one, pick a gear set to go with them]

Simplification 2:

If it's a spell, I want to put fast cast gear on. If it's a weaponskill or ability, and I have a gear set defined that matches that ability's name, equip that gear.


At the start, you can have dozens of lines describing all the details of what gear to choose for which circumstance. The first level of simplification/abstraction is better because you've moved all the gear out of the function and into the set definitions area, but it can still be rather long, and needs to be updated for every weaponskill or JA you might have or get. At the next level of simplification/abstraction you realize that all the information you need is already provided to you in the spell (parameter) table, and you just have to look up the set that matches that info.


Some things have already been abstracted for you. For example, you don't need a function: is_weaponskill(spellname). You can just look at spell.type and see if it says "WeaponSkill" to determine that.

Simplification 2 also takes advantage of the abstraction lua allows in how tables are named (as described in part 4 of the tutorial) by delegating the issue of figuring out which gear set to use for each ability to a simple check of whether a gear set table with the name of the ability has been defined. Basically, it's abstracted to the bare essentials of what you need.

Minimize the number of things you need to know within each function. If I have some "except for..." elements, then all I need to know is that there are exceptions. Another function should be in charge of determining if it's an exception, and merely tell my original function whether or not that's the case. Similarly for things like accuracy sets and whatnot: whether or not you're using an accuracy set is determined elsewhere; within the function that equips the gear, you merely apply it if it exists.


Abstraction is not a simple, "You must do this" rule. It's more a general state of mind -- a way of looking at the program and separating it into "Things I need to know or do right now (ie: within this function)", and "Things that I don't need to know how to do right now, and can push off to the side and fill in the details later (put in another function)." Don't try to fill in everything all at once; just paint in the broad strokes, and leave the details of "how" to another function.



Navigation
Part 1 - Basic Sets and Events
Part 2 - Conditionals and Testing
Part 3 - More on Conditionals
Part 4 - Tables
Part 5 - Abstractions
Part 6 - Asking the Right Questions
Part 7 - Library Tools
Author: Motenten
Date Created: 2014-04-25 18:39:14
Date Last Modified: 2014-05-08 17:15:36
Updates: 2
Bytes: 6446