Tool Subscript: The next step for scripting

Started by Touched July 31st, 2014 8:01 AM
  • 9253 views
  • 64 replies
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years


Subscript


Scripting revisited.

A subset of the Python language; scripting has never been easier




An open-sourced, cross-platform script editor.

Highly extensible, with a unique, easy-to-learn syntax - you'll never look back.



Features
  • Python-like syntax
  • Proper control flow - no more gotos
  • Type recognition
  • Custom commands, written in Python
  • Less numbers - Subscript knows the names of things, even when you change them
  • Embedded emulator, with debugger
  • Syntax highlighting and code completion
  • Modules allow you to do awesome things
  • Built in assembly and C support
  • Default parameters make for less typing
  • Full documenation, generated from source
  • More to come...



Downloads


Subscript now has an alpha release. This means that not everything works as it should, and is subject to change without notice. Once we have an official release, however, this process will be more streamlined.

Windows

Extract the archive to an empty folder, add a FireRed ROM called "test.gba" to the directory, and run gui.py. Make sure you have Python 3.4.

Linux

Install PyGObject, GtkSourceView and GtkSpell using your packaged manager. Clone the source from the GitHub repository, add a FireRed ROM called "test.gba" to the directory, and run gui.py.

Ubuntu

Open a terminal and run:

$ sudo apt-get install python3 git python3-gi gir1.2-gtksource-3.0 gir1.2-gtkspell3-3.0 gir1.2-clutter-1.0 python3-sphinx
$ sudo pip3 install sphinx_rtd_theme
$ git clone https://github.com/Touched/subscript.git
$ cd subscript
$ make html
$ python3 gui.py



Credits

Authors

Thanks to


Age 23
Male
Portugal
Seen July 5th, 2021
Posted October 26th, 2014
287 posts
9.7 Years
Wow, I can't believe no one has commented yet. This is very interesting.
1) I couldn't agree more with you when you said that it's hard to find the latest version, when my computer ceased to work, and I had to switch over to this same computer I'm using to write this comment, I had to ask a friend of mine to upload his XSE, 'cause I couldn't find one on the Internet.
2) I don't really know how bad XSE really is, 'cause I haven't ever learned other languages of any sort. I did start off with PokeScript (like most people), but I can't remember much about it, since I switched on over to XSE right after I asked for help here in the forums and someone (Spherical Ice :D) told me to switch on over to XSE. But hey, who knows, this case might be similar to Shiny Quagsire's MEH.
3) I don't really know how to feel about this, if you do suceed, I hope the community doesn't split into XSE and *insert your program's name*. That way there wont be as much support
4) Good luck ;)
Working on:


#fasterSneasel :D (nohomo)

Coolest IRC with the coolest people in the coolest rooms:
http://chat.linkandzelda.com:9090/?channels=romhacking,gogo,discovery,fluorite

Danny0317

Fluorite's back, brah

Age 22
Male
Seen February 19th, 2021
Posted March 11th, 2017
1,067 posts
9.7 Years
Well, this looks pretty awesome, I wish you the best of luck in this. The syntax looks pretty cool, and I really really really like this:

given = Flag(0x828)

and I was working on a ♥♥♥♥♥♥ program that teaches XSE XD

DJTiki

absolutely should have never given me the internet

Male
Florida, USA
Seen November 23rd, 2022
Posted April 11th, 2021
1,256 posts
8.9 Years
This looks pretty intresting n_n. If I were to advice something, it would to do something similar to what PokéScript did, and instead of using Hex numbers to determine a give item or chosen Pokémon, you just use the actual names. Can't wait to see how this will end up.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
Wow, I can't believe no one has commented yet. This is very interesting.
1) I couldn't agree more with you when you said that it's hard to find the latest version, when my computer ceased to work, and I had to switch over to this same computer I'm using to write this comment, I had to ask a friend of mine to upload his XSE, 'cause I couldn't find one on the Internet.
2) I don't really know how bad XSE really is, 'cause I haven't ever learned other languages of any sort. I did start off with PokeScript (like most people), but I can't remember much about it, since I switched on over to XSE right after I asked for help here in the forums and someone (Spherical Ice :D) told me to switch on over to XSE. But hey, who knows, this case might be similar to Shiny Quagsire's MEH.
3) I don't really know how to feel about this, if you do suceed, I hope the community doesn't split into XSE and *insert your program's name*. That way there wont be as much support
4) Good luck ;)
Yeah, I hope adopting this won't be too much of a problem - I (at the risk of sounding pompous) plan to make this so good that you can't NOT adopt it XD
XSE isn't bad. It's the actual scripting "language" that is. XSE is good at what it set out to do. I'm trying to abstract the language to make it more bearable. But I do think that it might become a problem, since not everyone is a scripter, and learning another language could be too much. But hey, we'll just have to wait and see how it pans out.

Well, this looks pretty awesome, I wish you the best of luck in this. The syntax looks pretty cool, and I really really really like this:

given = Flag(0x828)

and I was working on a ♥♥♥♥♥♥ program that teaches XSE XD
Thanks. The "language" has some type awareness. That way you can write functions in such a way that they'll do different things depending on the type of the argument. I use this extensively in the control flow: when you say "if flag" the program automatically converts this to a "checkflag" and a "if2" command. That way you don't have to type all of those lengthy "comparebytetofarbyte" commands.

This looks pretty intresting n_n. If I were to advice something, it would to do something similar to what PokéScript did, and instead of using Hex numbers to determine a give item or chosen Pokémon, you just use the actual names. Can't wait to see how this will end up.
Yeah, I plan to do that. Maybe I'll add Pokemon as a type, so you can just say give(BULBASAUR) to give a Pokemon, and give(POTION) to give an item.

Update:

I've added a new feature: In-script calculations. These are done at compile time, so no extra commands are run, but now you can say things like "lastresult = Var(0x8000 + 0xD) and it'll automatically compute the answer.

I haven't been able to do much work today - I've been at University all day. But hopefully I can get a significant portion done over the weekend. I won't promise anything, but I just might be able to release this as a command line tool soon. :)

esperance

Age 25
Male
OH
Seen October 8th, 2022
Posted January 11th, 2022
3,833 posts
12.9 Years
Well this is certainly a cool idea.

One issue I would have with it is the message system. What you have going looks nice, but one thing you can do with XSE and the like is reuse various texts, movements, etc. at a single offset. So, you could have a three msgbox commands that all call the same text. How would you handle something like this? This is one of the reasons other scripting tools use the section naming method.

Also, how do you plan on fitting goto commands in?
What are you so afraid of?
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
Well this is certainly a cool idea.

One issue I would have with it is the message system. What you have going looks nice, but one thing you can do with XSE and the like is reuse various texts, movements, etc. at a single offset. So, you could have a three msgbox commands that all call the same text. How would you handle something like this? This is one of the reasons other scripting tools use the section naming method.

Also, how do you plan on fitting goto commands in?
Yeah, I've thought about that. You can declare a variable, like a flag above:

catchphrase = Message("I say this a lot.")
# As a message
message(catchphrase)
# As a question
question(catchphrase)
You can do that with most "types", whether they be (script) variables, flags, raw values, movements, etc.

If you mean goto commands as in the regular sense, then I don't plan on fitting those in. All higher level languages do without them, and languages that have both goto and proper control flow (C/C++) strongly recommend that you leave them out altogether - they're unnecessary. However, I will include them, similar to the call command in the example I gave in the main post. But I don't see anyone needing them. I don't really see how I would implement them anyway.

esperance

Age 25
Male
OH
Seen October 8th, 2022
Posted January 11th, 2022
3,833 posts
12.9 Years
I guess I can see what you mean, but goto commands seem to be a major part of the scripting as whole. Just look at the Game Corner in FireRed, every person there uses a goto command to share a reused part of the script.

The reason higher level languages can leave out goto commands and such is because the effect can be gained by using loops and functions and whatnot, but that isn't exactly as feasible with the scripting format used by the games.
What are you so afraid of?
Female
Seen August 25th, 2017
Posted February 10th, 2016
25 posts
11.2 Years
I would recommend to keep the Games' Script Engine's syntax.

So use

textbox (u32 text, u8 callstdevent)

instead of

question (u32 text). This will make things more easier if you add commands or things like that.
A "script" could look like this:

function:
textbox (new String("Hello World"), 2);
exit();

That would be an authentic and efficient way of handling with scripts and using a good scripting language.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
I guess I can see what you mean, but goto commands seem to be a major part of the scripting as whole. Just look at the Game Corner in FireRed, every person there uses a goto command to share a reused part of the script.

The reason higher level languages can leave out goto commands and such is because the effect can be gained by using loops and functions and whatnot, but that isn't exactly as feasible with the scripting format used by the games.
I plan to add in while loops as well as functions (in fact, I'm right in the middle of doing so). However, you can still use those commands. You can call and goto as long as you know the offset. If you compile a script, you can call/goto it if you know the offset, but I'm making no plans to include dynamic offsets and such. You can just use a function, an if or while statement. However, if I think of a way to do it in Python syntax (I have to stick to it very closely, due to my implementation), I will try and add them. Maybe I can allow you to mark certain locations and jump back to them?

Additionally, I plan to allow integration with other things. For example, I plan to include automatic ASM routine insertion. So maybe I'll allow integration with a more traditional script. But that's not for now. I first want to get a fully functional version of this first. I am making every effort to make sure no features are left out. This is designed to be a superset of the existing scripting language after all.

I would recommend to keep the Games' Script Engine's syntax.

So use

textbox (u32 text, u8 callstdevent)

instead of

question (u32 text). This will make things more easier if you add commands or things like that.
A "script" could look like this:

function:
textbox (new String("Hello World"), 2);
exit();

That would be an authentic and efficient way of handling with scripts and using a good scripting language.
I don't quite understand why this is better. The thing is, these functions are created in a separate Python module - adding functions is trivial. For example, here is the implementation of the message and question functions (In Python)

@register
def message(string, keepopen=False):
    out = []
    out.append(script.Command.create('preparemsg', string.value))
    if keepopen:
        out.append(script.Command.create('callstd', 4))
    else:
        out.append(script.Command.create('callstd', 6))
    return out

@register
def question(string):
    out = []
    out.append(script.Command.create('preparemsg', string.value))
    out.append(script.Command.create('callstd', 5))
    return out
As you can see, the function implemented in Python takes the same arguments as the function in the script. If then interprets the arguments and returns real script commands that will be the commands compiled in the final script. It's trivial to add your own commands: all you do is write a function like this, and add the register decorator, and the function will be usable in a script.

That isn't even the game engine syntax though. A message is made by preparemsg, followed by callstd. So XSE already abstracts that. All I'm doing with the question command is hiding that callstd call.
Female
Seen January 12th, 2015
Posted August 1st, 2014
23 posts
9.4 Years
This looks super interesting & might be enough to actually be willing to play around with scripting overall!

I really like the 'message' and 'question' idea -- the less numbers a new person has to memorise, the more accessible scripting becomes. I would love to see this expanded into more commands.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
This looks super interesting & might be enough to actually be willing to play around with scripting overall!

I really like the 'message' and 'question' idea -- the less numbers a new person has to memorise, the more accessible scripting becomes. I would love to see this expanded into more commands.
Well, the commands aren't really the issue - it's really easy to add more. It's more the other features of the language that are the issue, but I'm really going to try and make it as easy as possible. For example, the givepokemon command won't need all those useless (?) zeroes. Default parameters will help a lot here - I hope to start a discussion about the most commonly used default parameters for each command, as well as frequently used commands.

UPDATE: I've just compiled my first script to hex. I'm going to decompile it in XSE soon, and see if all was compiled as expected.
EDIT: It's working :)
The script decompiles as expected. I just have a few more things to work out, and then I can release the source.

Does anyone have the XSE source? I can only find single .exe files, and I really need all of it's resource files (Pokemon list, etc.). I have no idea why all the links to it have been removed.

Spherical Ice

Age 25
Leicester, UK
Seen 17 Hours Ago
Posted February 20th, 2022
5,259 posts
15.2 Years
XSE uses .std files for things like Pokémon and items. https://www.dropbox.com/s/3by72bwg4zocwj8/XSE.zip (Chrome reckons this is unsafe, probably because of the .exe file)

This has all of them, as well as the source code.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
XSE uses .std files for things like Pokémon and items. https://www.dropbox.com/s/3by72bwg4zocwj8/XSE.zip (Chrome reckons this is unsafe, probably because of the .exe file)

This has all of them, as well as the source code.
Thanks so much! That's really going to save me a lot of time. I didn't know about the .std files. My copy of XSE didn't come with them. I didn't get a safety warning, but maybe that's because I'm on Linux :/

UPDATE: So I've altered the script in the main post slightly (with pointless changes), so you can see sample output:

Script:
given = Flag(0x828)
z = 0x800D
LASTRESULT = Var(z)
catch = "Are you taking good care\nof Charmander?"

if given:
    message(catch)
    message(catch)
    release()
    exit

question("Hello.\nSorry to trouble you.\nI can't take care\nof my Charmander.\pCan you take care of\nit for me?")
if LASTRESULT > 0 or LASTRESULT < 5:
    givepokemon(0x4, 0x5, 0x0, 0x0, 0x0, 0x0)
    fanfare(0x13E)
    message("{black}You received a Charmander!", True)
    waitfanfare()
    closeonkeypress()
    given = True
    question("{black}Would you like to give a\nnickname to Charmander?")
    if LASTRESULT:
        call(0x1A74EB)
    message("Please take care of\nCharmander.")
else:
    message("That's okay.\pI'm sure someone else will\ntake it.")

i = Var(0x4011)
while i < 4:
    message('Hey')
    i += 1 + 1

release()
exit
Output:
Interpreted script:
@section0:
	Command("checkflag 0x0828")
	Command("if1 0x01 @section1")
	Command("loadpointer 0x00 @section3")
	Command("callstd 0x05")
	Command("compare 0x800d 0x00")
	Command("if1 0x02 @section4")
	Command("compare 0x800d 0x05")
	Command("if1 0x00 @section4")
	Command("goto @section5")
	Command("compare 0x4011 0x04")
	Command("if1 0x00 @section11")
	Command("release")
	Command("end")
@section1:
	Command("loadpointer 0x00 @section2")
	Command("callstd 0x06")
	Command("loadpointer 0x00 @section2")
	Command("callstd 0x06")
	Command("release")
	Command("end")
@section2:
	b'\xbb\xe6\xd9\x00\xed\xe3\xe9\x00\xe8\xd5\xdf\xdd\xe2\xdb\x00\xdb\xe3\xe3\xd8\x00\xd7\xd5\xe6\xd9\xfe\xe3\xda\x00\xbd\xdc\xd5\xe6\xe1\xd5\xe2\xd8\xd9\xe6\xac\xff'
@section3:
	b'\xc2\xd9\xe0\xe0\xe3\xad\xfe\xcd\xe3\xe6\xe6\xed\x00\xe8\xe3\x00\xe8\xe6\xe3\xe9\xd6\xe0\xd9\x00\xed\xe3\xe9\xad\xfe\xc3\x00\xd7\xd5\xe2\xb3\xe8\x00\xe8\xd5\xdf\xd9\x00\xd7\xd5\xe6\xd9\xfe\xe3\xda\x00\xe1\xed\x00\xbd\xdc\xd5\xe6\xe1\xd5\xe2\xd8\xd9\xe6\xad\xfb\xbd\xd5\xe2\x00\xed\xe3\xe9\x00\xe8\xd5\xdf\xd9\x00\xd7\xd5\xe6\xd9\x00\xe3\xda\xfe\xdd\xe8\x00\xda\xe3\xe6\x00\xe1\xd9\xac\xff'
@section4:
	Command("givepokemon 0x04 0x05 0x00 0x00 0x00 0x00")
	Command("fanfare 0x013e")
	Command("loadpointer 0x00 @section7")
	Command("callstd 0x04")
	Command("waitfanfare")
	Command("closeonkeypress")
	Command("setflag 0x0828")
	Command("loadpointer 0x00 @section8")
	Command("callstd 0x05")
	Command("compare 0x800d 0x01")
	Command("if1 0x01 @section9")
	Command("loadpointer 0x00 @section10")
	Command("callstd 0x06")
	Command("goto @section0+8")
@section5:
	Command("loadpointer 0x00 @section6")
	Command("callstd 0x06")
	Command("goto @section0+8")
@section6:
	b'\xce\xdc\xd5\xe8\xb3\xe7\x00\xe3\xdf\xd5\xed\xad\xfb\xc3\xb3\xe1\x00\xe7\xe9\xe6\xd9\x00\xe7\xe3\xe1\xd9\xe3\xe2\xd9\x00\xd9\xe0\xe7\xd9\x00\xeb\xdd\xe0\xe0\xfe\xe8\xd5\xdf\xd9\x00\xdd\xe8\xad\xff'
@section7:
	b'\xfc\x01\x01\xd3\xe3\xe9\x00\xe6\xd9\xd7\xd9\xdd\xea\xd9\xd8\x00\xd5\x00\xbd\xdc\xd5\xe6\xe1\xd5\xe2\xd8\xd9\xe6\xab\xff'
@section8:
	b'\xfc\x01\x01\xd1\xe3\xe9\xe0\xd8\x00\xed\xe3\xe9\x00\xe0\xdd\xdf\xd9\x00\xe8\xe3\x00\xdb\xdd\xea\xd9\x00\xd5\xfe\xe2\xdd\xd7\xdf\xe2\xd5\xe1\xd9\x00\xe8\xe3\x00\xbd\xdc\xd5\xe6\xe1\xd5\xe2\xd8\xd9\xe6\xac\xff'
@section9:
	Command("call 0x1a74eb")
	Command("goto @section4+11")
@section10:
	b'\xca\xe0\xd9\xd5\xe7\xd9\x00\xe8\xd5\xdf\xd9\x00\xd7\xd5\xe6\xd9\x00\xe3\xda\xfe\xbd\xdc\xd5\xe6\xe1\xd5\xe2\xd8\xd9\xe6\xad\xff'
@section11:
	Command("loadpointer 0x00 @section12")
	Command("callstd 0x06")
	Command("addvar 0x4011 0x02")
	Command("compare 0x4011 0x04")
	Command("if1 0x00 @section11")
	Command("goto @section0+11")
@section12:
	b'\xc2\xd9\xed\xff'

Compiled script:
Script size: 494 bytes
2B 28 08 06 01 39 00 80 08 0F 00 73 00 80 08 09 05 21 0D 80 
00 00 06 02 D4 00 80 08 21 0D 80 05 00 06 00 D4 00 80 08 05 
13 01 80 08 21 11 40 04 00 06 00 CD 01 80 08 6C 02 0F 00 4B 
00 80 08 09 06 0F 00 4B 00 80 08 09 06 6C 02 BB E6 D9 00 ED 
E3 E9 00 E8 D5 DF DD E2 DB 00 DB E3 E3 D8 00 D7 D5 E6 D9 FE 
E3 DA 00 BD DC D5 E6 E1 D5 E2 D8 D9 E6 AC FF C2 D9 E0 E0 E3 
AD FE CD E3 E6 E6 ED 00 E8 E3 00 E8 E6 E3 E9 D6 E0 D9 00 ED 
E3 E9 AD FE C3 00 D7 D5 E2 B3 E8 00 E8 D5 DF D9 00 D7 D5 E6 
D9 FE E3 DA 00 E1 ED 00 BD DC D5 E6 E1 D5 E2 D8 D9 E6 AD FB 
BD D5 E2 00 ED E3 E9 00 E8 D5 DF D9 00 D7 D5 E6 D9 00 E3 DA 
FE DD E8 00 DA E3 E6 00 E1 D9 AC FF 79 04 00 05 00 00 00 00 
00 00 00 00 00 00 00 31 3E 01 0F 00 51 01 80 08 09 04 32 68 
29 28 08 0F 00 6F 01 80 08 09 05 21 0D 80 01 00 06 01 A3 01 
80 08 0F 00 AD 01 80 08 09 06 05 2C 00 80 08 0F 00 20 01 80 
08 09 06 05 2C 00 80 08 CE DC D5 E8 B3 E7 00 E3 DF D5 ED AD 
FB C3 B3 E1 00 E7 E9 E6 D9 00 E7 E3 E1 D9 E3 E2 D9 00 D9 E0 
E7 D9 00 EB DD E0 E0 FE E8 D5 DF D9 00 DD E8 AD FF FC 01 01 
D3 E3 E9 00 E6 D9 D7 D9 DD EA D9 D8 00 D5 00 BD DC D5 E6 E1 
D5 E2 D8 D9 E6 AB FF FC 01 01 D1 E3 E9 E0 D8 00 ED E3 E9 00 
E0 DD DF D9 00 E8 E3 00 DB DD EA D9 00 D5 FE E2 DD D7 DF E2 
D5 E1 D9 00 E8 E3 00 BD DC D5 E6 E1 D5 E2 D8 D9 E6 AC FF 04 
EB 74 1A 00 05 0C 01 80 08 CA E0 D9 D5 E7 D9 00 E8 D5 DF D9 
00 D7 D5 E6 D9 00 E3 DA FE BD DC D5 E6 E1 D5 E2 D8 D9 E6 AD 
FF 0F 00 EA 01 80 08 09 06 17 11 40 02 00 21 11 40 04 00 06 
00 CD 01 80 08 05 38 00 80 08 C2 D9 ED FF 
Function main took: 0.0065411969990236685 seconds.
It looks like most of its working. I've changed the returns and calls to gotos to avoid the nesting problem, and I've seemingly got most of the control flow working. It looks like I'm ready to publish, so I'll write up a quick CLI and then upload a demo :)

ASIDE: I'm quite happy with that time. That time includes opening the script, compiling and writing the binary data to a ROM, so the utility is very speedy.
Age 23
Male
Portugal
Seen July 5th, 2021
Posted October 26th, 2014
287 posts
9.7 Years
Hey, I have a question.
In this begginig part:
given = Flag(0x828)
z = 0x800D
LASTRESULT = Var(z)
catch = "Are you taking good care\nof Charmander?"
Why is the flag set out like this:
given = Flag(0x828)
And the Var isn't set out like this:
LASTRESULT = Var(0x800D)
But like this:
z = 0x800D
LASTRESULT = Var(z)
?
Working on:


#fasterSneasel :D (nohomo)

Coolest IRC with the coolest people in the coolest rooms:
http://chat.linkandzelda.com:9090/?channels=romhacking,gogo,discovery,fluorite
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
Hey, I have a question.
In this begginig part:
given = Flag(0x828)
z = 0x800D
LASTRESULT = Var(z)
catch = "Are you taking good care\nof Charmander?"
Why is the flag set out like this:
given = Flag(0x828)
And the Var isn't set out like this:
LASTRESULT = Var(0x800D)
But like this:
z = 0x800D
LASTRESULT = Var(z)
?
That's just a demonstration I believe, to show that it would accept local variables as values.
Yeah, it's just a demonstration. You could also do something like
z = 0x800D
LASTRESULT = Var(z + 10)
if you needed it. I just made that file to test the features I've put in. But don't worry - I'll document everything when I've finished.
Age 23
Male
Portugal
Seen July 5th, 2021
Posted October 26th, 2014
287 posts
9.7 Years
Ah, adding those variables definitely makes things better.
Will you also allow us to create functions?
He said it will be Open Sourced, so make what youwhat you will from that
Also, what will the program's name be?
TNSSE? (The next step Script Editor)
Maybe just TNS.
Any ideas? (not that it matters too much as of right now)
Working on:


#fasterSneasel :D (nohomo)

Coolest IRC with the coolest people in the coolest rooms:
http://chat.linkandzelda.com:9090/?channels=romhacking,gogo,discovery,fluorite

Spherical Ice

Age 25
Leicester, UK
Seen 17 Hours Ago
Posted February 20th, 2022
5,259 posts
15.2 Years
Oh, actually, I have a request for when you get regular scripting working. Do you think it'd be possible to add support for multiple scripting engines? That way, one could use this for both battle scripting and regular scripting. That would be a great asset for the community, particularly with how many people are unable to use BSP.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
Ah, adding those variables definitely makes things better.
Will you also allow us to create functions?
Yeah, but I haven't quite worked out the mechanics. I'm thinking of using the import tools to perform multiple functions:
  • Import ASM routines
  • Python Modules
  • Binary Data
  • Definition lists

So then you'll be able to say

import routine
thumb(routine)
And it'll automatically insert the routine (and align) and a callasm offset + 1. Also, if you import a Python module, you'll be able to add functions - I've added an example of how this works (with decorators) in another post.

But I also plan to use the regular Python syntax for functions:

def function(args):
    pass
But I'm really not sure how that will be translated. Maybe a call command and end with a return? Set lastresult? I've yet to work something out. If someone wants to suggest something they'd be more than welcome.

He said it will be Open Sourced, so make what youwhat you will from that
Also, what will the program's name be?
TNSSE? (The next step Script Editor)
Maybe just TNS.
Any ideas? (not that it matters too much as of right now)
I really haven't thought of a name for this to be honest. I've named the Python module I wrote "subscript", but I'm not sure that that's a good name. I'm not really a fan of all the acronyms, so I might pick something that's one word - to make it stand out more? But suggestions are welcome. I'm coding a test GUI now, so I'll probably need a name soon.

Oh, actually, I have a request for when you get regular scripting working. Do you think it'd be possible to add support for multiple scripting engines? That way, one could use this for both battle scripting and regular scripting. That would be a great asset for the community, particularly with how many people are unable to use BSP.
Yeah, I was thinking about doing that. I've made it modular as best I can, but some things will definitely need to be rewritten for different scripting engines (the types and control flow logic, for example). But I'll add it to the planned features list.

esperance

Age 25
Male
OH
Seen October 8th, 2022
Posted January 11th, 2022
3,833 posts
12.9 Years
A way you could set up the coding to work with the custom functions is to just have everything in a function of some kind, and require a main() function for the start of the script.

Sort of like this...
# This would be a requirement
def main():
     ...
     do_something()
     if ... = False:
          do_something_2()
     ...
     end

# And then the user can define as many of these as they want.
def do_something():
     ...
     # It could be a return, which would tell you to make references to it a call
     return

def do_something_2():
     ...
     # Or it could be a end, which would tell you to use a goto
     end
How does that look?
What are you so afraid of?
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.6 Years
Ok, I downloaded this and python 3.4, how do I make it function?
If you wish to check out the demo, you can use the command line interface as per the example in the first post. Type "python3 cli.py --help" to see a list of available flags. It won't help much if you want to make a script with it though - I haven't implemented many functions.

A way you could set up the coding to work with the custom functions is to just have everything in a function of some kind, and require a main() function for the start of the script.

Sort of like this...
# This would be a requirement
def main():
     ...
     do_something()
     if ... = False:
          do_something_2()
     ...
     end

# And then the user can define as many of these as they want.
def do_something():
     ...
     # It could be a return, which would tell you to make references to it a call
     return

def do_something_2():
     ...
     # Or it could be a end, which would tell you to use a goto
     end
How does that look?
Yeah, that's a good idea. Maybe I could also make it set lastresult if you try to return a value? I'm not so sure about the main method though - what happens to the code outside of it? But I'll definitely use the other two, thanks :)
Maybe I'll also do inline functions? If you only call a particular function once, a call is useless? Or is that not such a great idea (maybe you want to have separate entry points for your script)?