itsyfox
01-08-2007, 10:47 PM
Alright, don't kill me, but...
I think there might be better languages than CScript and ASM to use for scripting in Zelda Classic. If it wasn't too much trouble, would you change languages?
Would it be too much trouble?
I know a lot of people would probably complain that they had to rewrite their scripts, but let me explain...
I'm suggesting Python. Not to run the graphics, but to provide the scripting interface, at least. It also 'compiles' to it's own byte-code, so having the ASM layer for efficiency would most likely be unneccessary, too...
Here's why:
1) Python has a wide variety of data types, including multi-valued types such as tuples and dictionaries.
2) Python has classes. You can write your own classes to use, and child them to existing classes, declaring their type if desired.
3) Python is designed to be pretty. No semicolons or curly-braces to worry about, instead, it's the indentation itself that designates blocks. And since it's formal to indent anyways, that simply takes out unnecessary characters that often trip you up if you aren't careful, and leaves only the more obvious (and very clean looking) indentation.
4) Python has a wide variety of commands that can be used, but there's not too much overlap.
5) Python is a very easy language to learn. There are more words than symbols, and not much of the language is cryptic at all. Most of the commands are straightforward, and mean what you'd guess.
6) It really knows how to use integers! Yet you can still do all your bit-shifting and such when you want. Plus you can AND and OR your conditionals together, reducing the number you need.
7) It's highly portable, and will still work on all three platforms.
8) There's already a Python binding for Allegro, more than one, but here's one I found: http://sourceforge.net/projects/pyallegro/
9) Bindings are also fairly easy to make, using the C libraries version of the interpreter, or others.
Let's have a small example. I'll make up some code in ZScript, then in Python. For the Python, I'll basically just make Python-style commands with the same names as the ZScript commands.
ZScript code (not necessarily functional):
ffc script foo {
import "std.zh";
void run() {
int a_variable = 4;
while(true) {
while(Screen->NumItems() < a_variable) {
Screen->CreateItem(I_RUPEE1);
item thisitem = Screen->LoadItem(Screen->NumItems());
int randx = rand(16) * 10 * 16 & 224;
int randy = rand(16) * 10 * 11 & 224;
thisitem->X = randx;
thisitem->Y = randy;
}
Waitframe();
}
}
}
Equivalent Python code:
ffc script foo
"""
Python doesn't have to be contained entirely inside functions. What was outside of all functions would be run first.
Global scope exists for any loop not in a function; otherwise anything declared inside a function is function-local scope.
The same is true for anything created in a class, in order to reference a class variable you use dot syntax.
Normally you'd use dot syntax for imported commands too, but since you did 'from x import *' instead of just 'import x',
you can use all the commands directly. This allows you to import specific functions and classes, too, rather than a whole file.
"""
from std import * #import what is currently std.zh but would probably be std.py or std.zpy or something
#init some variables
a_variable = 4
create = Screen.CreateItem
load = Screen.LoadItem
items = Screen.NumItems
while 1 #do this every frame
while items() < a_variable #do this while we're below our max
create(I_RUPEE1) #create a green rupee
thisitem = load(items()) #store the current item
randx = rand(16) * 16 #get a random x that's on a screen tile
randy = rand(11) * 16 #get a random y that's on a screen tile
#move the item to the random coordinate
thisitem.X = randx
thisitem.Y = randy
Waitframe()
#and we're done!
You could also create a class of ffc, even for a generic type of custom enemies! You could create a class based on any existing classes, and give it any functions, variables, and subclasses you wanted!
Also, by setting the value of arguments in a function declaration, you can have optional arguments. for instance, the python code:
function foo(x, y, z)
would require you supply x, y, and z, but the code:
function foo(x=0, y=0, z=0)
would allow the function to have default values of 0,0,0 and be called with any or none of the arguments!
Python is a wonderful language. Wonderful. If it were used instead of ZScript, I'm sure the initial grumble over re-writing code would turn into appreciation for a really nice language.
Also, when you saved a script to a slot, it would compile python byte code instead of ASM. That way, you only need work with one language, but you have all the functionality right there, high and low level both.
Then all the developers need is to be able to compile their own python bytecode right into the engine, to make development far more modular and far less hard-coded. ^_^
And heck, if this were to be done, with as few ZScript commands as there are anyways, I'd be willing to spring and write a ZScript->ZPython converter! Maybe ZASM too, but I haven't learned ZASM yet.
I think there might be better languages than CScript and ASM to use for scripting in Zelda Classic. If it wasn't too much trouble, would you change languages?
Would it be too much trouble?
I know a lot of people would probably complain that they had to rewrite their scripts, but let me explain...
I'm suggesting Python. Not to run the graphics, but to provide the scripting interface, at least. It also 'compiles' to it's own byte-code, so having the ASM layer for efficiency would most likely be unneccessary, too...
Here's why:
1) Python has a wide variety of data types, including multi-valued types such as tuples and dictionaries.
2) Python has classes. You can write your own classes to use, and child them to existing classes, declaring their type if desired.
3) Python is designed to be pretty. No semicolons or curly-braces to worry about, instead, it's the indentation itself that designates blocks. And since it's formal to indent anyways, that simply takes out unnecessary characters that often trip you up if you aren't careful, and leaves only the more obvious (and very clean looking) indentation.
4) Python has a wide variety of commands that can be used, but there's not too much overlap.
5) Python is a very easy language to learn. There are more words than symbols, and not much of the language is cryptic at all. Most of the commands are straightforward, and mean what you'd guess.
6) It really knows how to use integers! Yet you can still do all your bit-shifting and such when you want. Plus you can AND and OR your conditionals together, reducing the number you need.
7) It's highly portable, and will still work on all three platforms.
8) There's already a Python binding for Allegro, more than one, but here's one I found: http://sourceforge.net/projects/pyallegro/
9) Bindings are also fairly easy to make, using the C libraries version of the interpreter, or others.
Let's have a small example. I'll make up some code in ZScript, then in Python. For the Python, I'll basically just make Python-style commands with the same names as the ZScript commands.
ZScript code (not necessarily functional):
ffc script foo {
import "std.zh";
void run() {
int a_variable = 4;
while(true) {
while(Screen->NumItems() < a_variable) {
Screen->CreateItem(I_RUPEE1);
item thisitem = Screen->LoadItem(Screen->NumItems());
int randx = rand(16) * 10 * 16 & 224;
int randy = rand(16) * 10 * 11 & 224;
thisitem->X = randx;
thisitem->Y = randy;
}
Waitframe();
}
}
}
Equivalent Python code:
ffc script foo
"""
Python doesn't have to be contained entirely inside functions. What was outside of all functions would be run first.
Global scope exists for any loop not in a function; otherwise anything declared inside a function is function-local scope.
The same is true for anything created in a class, in order to reference a class variable you use dot syntax.
Normally you'd use dot syntax for imported commands too, but since you did 'from x import *' instead of just 'import x',
you can use all the commands directly. This allows you to import specific functions and classes, too, rather than a whole file.
"""
from std import * #import what is currently std.zh but would probably be std.py or std.zpy or something
#init some variables
a_variable = 4
create = Screen.CreateItem
load = Screen.LoadItem
items = Screen.NumItems
while 1 #do this every frame
while items() < a_variable #do this while we're below our max
create(I_RUPEE1) #create a green rupee
thisitem = load(items()) #store the current item
randx = rand(16) * 16 #get a random x that's on a screen tile
randy = rand(11) * 16 #get a random y that's on a screen tile
#move the item to the random coordinate
thisitem.X = randx
thisitem.Y = randy
Waitframe()
#and we're done!
You could also create a class of ffc, even for a generic type of custom enemies! You could create a class based on any existing classes, and give it any functions, variables, and subclasses you wanted!
Also, by setting the value of arguments in a function declaration, you can have optional arguments. for instance, the python code:
function foo(x, y, z)
would require you supply x, y, and z, but the code:
function foo(x=0, y=0, z=0)
would allow the function to have default values of 0,0,0 and be called with any or none of the arguments!
Python is a wonderful language. Wonderful. If it were used instead of ZScript, I'm sure the initial grumble over re-writing code would turn into appreciation for a really nice language.
Also, when you saved a script to a slot, it would compile python byte code instead of ASM. That way, you only need work with one language, but you have all the functionality right there, high and low level both.
Then all the developers need is to be able to compile their own python bytecode right into the engine, to make development far more modular and far less hard-coded. ^_^
And heck, if this were to be done, with as few ZScript commands as there are anyways, I'd be willing to spring and write a ZScript->ZPython converter! Maybe ZASM too, but I haven't learned ZASM yet.