[Ante-developer] A Skill Script Language
Brought to you by:
roguestar191
|
From: Matthew <rog...@co...> - 2006-01-01 03:40:18
|
Ok, as some of you already know I want to impliment a skill script
language, so all skills are scripted, compiled into bytecode scripts which
are stored in the application as skills, and when evoked the script is
executed with the arguments being passed to it. Scripts will be able to be
reloaded at runtime, no more rebooting to make a new skill work.
What this means is skills will be purely modular. In order to accomplish
this, I wish to create a _decent_ language.
To make a decent language, the entire specification must be written out in
(preferably) english, with everything that could possibly be needed being
defined.
I have some stuff, but not everything, skills should be able to interact
with everything in every way, which all must be thought of before hand.
This will be a major turning point in the development of the ANT engine,
where everything so far has been designed for a very specific purpose,
this part will be designed for a very very general purpose and accomplish
a lot.
Ideas would be greatly appreciated. What do you like from languages you've
used, what do you not like? What would be a good form? I'm going to try to
go for multi-paradigm, so all ideas are welcome, from prodedural
programming, global programming, to object oriented programming (I do not
wish to include macros however, #include I will include, and macro's. I
also want to create a simply compiler interface which looks like:
( *ish* = input starts here)
prompt> *ish* LoadSkill
Script File: *ish* A.script
Loading script file A, B, and C. (script A would #include "B.script"
which may #include "C.script" or A may #include "A.script", etc.)
I'm wondering, maybe it should work like java, requiring int main() to be
inside an object. A special identifier could be used to define the "main"
object, using int main(int argc, char *argv[]) inside the main object .
This is the execution function, when this skill is "cast" or used or
however you want to think about it, this function is called.
Other entry points can be defined to do other behaviors as well. Such as:
char *[]Restrictions() { char *restrictions[] = { "Race_elf",
"Class_mage", "blah" }; return restrictions; };
and maybe:
char *[]OnlyAllow() { char *only[] = { "Class_cleric"; return only;};
With this setup so far, only allow clerics that arn't elfs or blah's, mage
doesn't really matter because cleric is the only class allowed.
And global values can be defined, only if they're in the script.
So basically, if we have the script:
Skill Name { // Main identified is the "Skill" keyword, name is the access
word used to access it by people that have it or want to learn it. from
someone who does
char *[]Restrictions() { char *no[] = { "Race_elf", "Class_mage" };
return no;
char *[]Only() { char *only[] = { "Class_ant" }; };
//But why should we have to define the function right here, it makes
implimentation messy.
//just look at main, there's a thought about that below
int main(int argc, char *argv[]) {
Target target; // special Target class to defined targets, wether it be
an item, mob, room, area, etc
if(argc > 1) {
target = SpecialGlobalFunctionToGetTarget(argv[1]);
} else {
target = GetCasterCurrentTarget;
}
if(target == NULL) {
Caster cast; // special object defines the caster, and contains ALL
information about it, class name(if any), race name, level (if any), a
list of all skills, this skills current "known percentage" and whatever
else.
if(argc > 1)
print(cast, "There is nothing named " + argv[1] + " here!\n");
else print(cast, "Do " + Skill.Name + " on what?" ); // Skill.Name
would be a special feature that prints rtti information, the Name you name
this special "Skill" module
} else {
Caster TheCaster;
Target TheTarget;
TryDamage(100, TheCaster, TheTarget); // special function which uses a
special scripted combat system, it could do special checks, doing a
maximum damage of 100, probobly reduced, sometimes completely avoided
}
}
//The alternative would be like:
int main(int argc, char *argv[]);
};
//then here outside the class just like C++
int SkillName::main(int argc, char *argv[]) {
Do everything in the int main() above..
}
Then there's inheritence, where do we get this "TryDamage" routine,
perhaps we could:
#include "combat.script"
which contains an object:
//I'm not sure private/public/protected is needed , or is it?
class Combat {
TryDamage(int amount, Caster castee, Target target){
special checks, offset ammount
use special callback function to damage target
callback(damage, target, amount, "IfSuccessMessage" || "IfFailMessage");
//the success and fail messages must be passed by int main() to here as
well as the amount, target, castee, etc.
} // By default, it will pass everything by reference
} // With more functions perhaps
Then the Skill Name { would be changed to Skill Name : Combat
with #include "combat.script" at the top.
Also, an optional Queue and Reverse queue will be added. So when a skill
is executed it can either work right away, do nothing else, work right
away and make it so no other skills can be cast until it cools down with
the option of it printing messages at a minimum of every second, or do
preperation messages while not allowing other skills, and executing it at
the time of cast.
With this layout, things like Level restrictions could be added easily, or
Skill restrictions. Then maybe Mob teachers, you define a mob with a
special "teacher tag" which must match the tag exactly as you define in
the script, and only that mob can teach, regardless of it's name (So you
can have 2 frodo's roaming about, but only 1 is real and can teach you the
"smoke rings" skill which lets you blow smoke rings when you smoke a pipe
or cigarette or use your imagionation.
The same interpretor will not only do skill scripts, it also does http
preprocessing at the moment. It will probobly do mob scripting as well if
Skill Scripting works.
This implimentation will put the control in the hands of the typical non
programming mud admin, hiding complexity, allowing features to be added
and testing without worrying about crashing everything, while allowing
programmers to focus on just that, programming, and game developers to
focus on making their game.
Thoughts would be greatly appreciated, ideas, ideas on how to impliment
the parser to compile the script to bytecode would be greatly appreciated
(Pointers to free online compiler books that would help me, Ideas on what
skills should be able to affect, the Target and Caster special objects
should be able to directly access strings on the desired object, so things
such as "journals" or "notepads" can be made on anything using a skill
which impliments such a thing, storing messages in the description string
on an object which will automatically be parsed if it contains special
markers.. it'll make much more sense once it's implimented).
The entire bytecode definition is defined on the main ANT server,
http://ant.infice.com:5555 or if that doesn't work:
http://roguestar.dynu.com:5555 (ant.infice.com seems to go down a lot
lately), but is not yet in a constant state, meaning, I'm still upgrading
it. I plan to add lowlevel simple string support, to hopefully make
strings easier to impliment in the higher level language )
To sum up in this huge ass paragraph that may or may not be to long, my
vision is: A C/C++ like language with many access points for different
behaviors (if it's stored in the queue, a function may be called every 1
second with an int of how much time there is left in the queue so it can
print out a message if it's coded to do so.)
Supporting proceduaral and object oriented programming, compiled into a
bytecode language to be interpreted at run-time, for easy "plug-n-play"
behavior with the largest part of the game aspect.
The advantage of a bytecode interpretor/compiler design is that it's
faster than directly interpreting the high level language, and scripts can
be compiled once and run many times in the bytecode language, and released
in a "binary" form. This will be an advantage for both open source and
non-open source muds, people who don't want to release the source to thier
skills arn't required to, they wrote them, but they can still share "a
version" of their skills with other muds for free, or even for a price, as
a bytecode only, Which I hope would promote sharing of ideas, and easy
upgrading of muds for non-developers that don't want to bother with
coding, but want to have the cool stuff.
And by including everything into the script when it's compiled, if it's
output to bytecode, there are zero dependencies, it doesn't need the
original .script files to run, so if you change the combat system to make
a skill, compile it, then change the combat system again for another
skill, the combat system will behave in each skill the way you modified it
to at _that_ time. this will help with code re-use, as well as easy
sharing. It shouldn't create confusion, but could lead to "lost" code, but
if you're using cvs or subversion to develop this is no problem.
No, you won't be able to link C or C++ libraries in, unless someone makes
a C or C++ compiler to ANT-Bytecode (Most C or C++ compilers compile to
one form of assembly or another, so I see no reason why it's not possible
for an existing C or C++ compiler to compile to ant-bytecode, although to
support all features it definitally needs work, which would then allow
them to be linked in, but I'm definitally not going that far by myself,
for another 10 years at least....
Oh and Happy New Years to all!
--Rogue
--Developer of ANT
--
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
|