Skip to content

Commit cd0c07c

Browse files
author
AWSWCommunity
authored
Merge pull request #6 from scrlys/documentation
Update documentation
2 parents a4eb9c1 + 912dd1f commit cd0c07c

File tree

4 files changed

+246
-206
lines changed

4 files changed

+246
-206
lines changed

API.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
2+
## Api
3+
4+
To access all the helper functions for modifying game behaviour, put ```from modloader.modlib import base as ml``` at the top of your mod file. ```modlib``` comes preloaded with a class called ```AWSWModBase``` initialized in the ```base``` member of ```modlib```. The line above will automatically redeclare ```base``` as ```ml```. Useful functions in the class are listed below.
5+
6+
#### ```Screen getscreen(string screen_name)```
7+
This gets a Ren'py Screen object(long name: renpy.display.screen.Screen). This is used to get a handle to a screen you might want to edit, such as the status overlay or the main_menu.
8+
#### ```SLScreen getsls(String screen_name)```
9+
getsls is a helper function for getting the executable part of the Screen. This is a tree of SL* objects that Ren'py steps through and executes. You will be hooking and editing these if you're interacting with a screen.
10+
#### ```Node findlabel(string label_name)```
11+
Looks for a label (defined as 'label example:') in the Ren'py language. It will return a renpy.ast.Label object associated with it.
12+
#### ```Node hooklabel(string label_name, Function func=None)```
13+
Takes a label name and returns an ASTHook object with utilities for hooking the label. ```func``` is called whenever the hook node is executed. Returning True in ```func``` will result in the hook not advancing to the next node.
14+
#### ```ASTHook hook_opcode(Node node, Function func=None)```
15+
Hooks a node. An instance of ASTHook will be created, chained to ```node```, and returned by this function. After ```node``` executes, the hook will run, and then control flow will will be passed to the hooked node's original next instruction. Set the ```.next``` member to control what statement is called after the hook executes. If ```func``` is passed to ```hook_opcode```, it will be executed when with the hook and can control execution by returning ```True``` and setting ```hook.next```. The hook class will be passed to ```func```.
16+
#### ```ASTHook call_hook(Node node, Node dest_node, Function func=None)```
17+
Hooks a node, then upon execution, jumps to dest_node and pushes the instruction after node to the callstack. Using 'return' in Ren'py code thereafter will return to the node+1 operation.
18+
#### ```ASTHook jump_ret(Node node, Node dest_node, Node ret_node, func=None```
19+
This will hook ```node```, redirecting execution to dest_node after node is executed. ret_node will be pushed on to the callstack, so calling return after dest_node will pass program execution to ret_node. ```func``` will be executed with the hook as a parameter when the hooking node executes. The hooking node will be returned from this function.
20+
#### ```Node searchPostNode(Node node, NodeClass toFind, int searchLength=200)```
21+
Takes a node (which can be found via findlabel or other functions) and searches for a node proceding it of type toFind. Searches a maximum of searchLength operations, and returns None if the instruction isn't found.
22+
#### ```Bool nullPyexpr(SLScreen scr, String comparison)```
23+
Takes an SLScreen object and searches for any if statements (SLIf objects) that are direct children of it. Any if statements(and their child blocks) that match the comparison string are removed.
24+
#### ```list findMenu(String comparison)```
25+
#### ```list findMenu(list comparisonList)```
26+
Will search for a Menu with an option that is equal to comparison, or contains all options in comparisonList. Returns a list of menus(ast.Menu) matching the specifications.
27+
#### ```Node findSay(String comparison)```
28+
Searches for a say node(ast.Say) matching the string provided. These can be anything a character says.
29+
#### ```Node stepOp(Node node, int n)```
30+
Will return the operation that exists n nodes after node. This will skip hooking nodes.
31+
#### ```Any getRGlobal(key)```
32+
When using '$ myVar = "yyy"' statements in the Ren'py language, the variables are stored in localized dictionary within Ren'py, normally inaccessable to mods. Use this to access the value of a variable with 'key' name. For example, calling modlib.getRGlobal('myVar') would return a string value of "yyy" if the above statement was run.
33+
#### ```setRGlobal(key, value)```
34+
Equivalent to '$ key = value' from within the Ren'py language. Use this to marshal data from your mod to a Ren'py script.
35+
#### ```AWSWMenuHook getMenuHook(Node menu)```
36+
Returns the AWSWMenuHook class instance for that particular menu. This will allow you to add, remove, or modify choices.
37+
#### ```AWSWHomeHook getHomeHook()```
38+
Returns the AWSWHomeHook class instance responsible for managing the ambassador apartment.
39+
#### ```AWSWEndingHooks getEndingHooks()```
40+
Returns the AWSWEndingHooks class instance responsible for managing ending hooks.
41+
#### ```Node findPyStatement(String code)```
42+
Searches the entire game for a single line python statement in Ren'py code. The spaces on the end of the instruction are trimmed by Ren'py, so to find ```$ testVar = True```, pass "testVar = True" to the function.
43+
## ```class AWSWMenuHook```
44+
The AWSWMenuHook class is responsible for editing a menu, the point in game where the player has options to modify the dialogue tree. After obtaining a reference to a menu node, pass the node into ```getMenuHook``` to access this class's functions. The useful functions are listed below:
45+
#### ```deleteItem(String label)```
46+
Deletes an option from the menu with label title.
47+
#### ```list getOptionCode(String option)```
48+
This function will return a list of instructions that would be executed if a user were to pick the option matching ```option```. You really only need to acess the first node in the list. Each node is chained to the next, similar to ASTHook.
49+
#### ```getItems()```
50+
Returns a list of all the options in the menu. Each member of the list is a tuple of (String optionTitle, String conditionalStatement, list opcodes).
51+
#### ```setConditional(String label, String newConditional)```
52+
Sets the condition for displaying the option to the player of the option with the title of label.
53+
#### ```addItem(String label, Node hook, condition="True") ```
54+
#### ```ASTHook addItem(String label, Function hook, condition="True")```
55+
Adds an option to the menu with ```label``` title and ```condition``` condition. If ```hook``` is a node, then when the user selects this option, the game will jump to that node. If hook is a function, an ASTHook instance will be created and returned. The function will be executed when the user selects that option and you will be responsible for redirecting control flow. ```condition``` will be evaluated as a Python expression when the menu is shown. Evaluating as false will mean the menu option doesn't appear to the player.
56+
57+
#### ```ASTHook addItemCall(String label, Node hook, condition="True")```
58+
Performs the same function as ```addItem``` does with a node, except ```hook``` will be called, meaning you can have a ```return``` instruction to continue normal game execution.
59+
## ```class AWSWHomeHook```
60+
The AWSWHomeHook class is responsible for editing the menu that appears in the Ambassador apartment, where the player can choose a character route. The exposed functions are listed below.
61+
62+
#### ```addRoute(title, Node destination, condition="True")```
63+
Adds a route to all chapter menus that displays if condition evaluates to true. When the user selects this option, the game will pass control to the destination Node. Executing a return instruction will redirect control back to the menu and continue the game normally.
64+
#### ```hookChapterChange(Node hook_node)```
65+
#### ```hookChapterChange(Function func)```
66+
If the first argument to this function is a function, it will be called whenever the chapter changes(chapter 1 to chapter 2, etc.). If the first argument is a node, the current instruction will be pushed to the callstack and the game will jump to ```hook_node```. Using the ```return``` statement in Ren'py code will jump back to the original game code.
67+
#### ```addAnwerMachineCheckHook(Node dest_node)```
68+
#### ```addAnwerMachineCheckHook(Function func)```
69+
Will add a hook to the point where it is determined whether the answering machine dialogue should pop up. If you're passing a node to an additive code label, run ```return True` if the dialogue should pop up, and ```return False``` if it should not. If using a python function, return True if it should show and False if it should not.
70+
#### ```addAnswerMachineScene(Node dest_node)```
71+
#### ```addAnswerMachineScene(Function func)```
72+
Will add a hook that will be called after the message check returns true. If the first argument is a node, the game will jump to the specified node. Make sure you have a return statement to resume normal execution in this case. If the argument is a function, ```func``` will be called with the hooking node as the only argument. Returning false in this python function will prevent the next instruction from being executed, meaning you'll need to manually jump somewhere next.
73+
#### ```hookChapter1(Node node)```
74+
Will add a hook after all variables are declared in chapter 1. This is called right after the played enters the ambassador apartment, but before the route menu is displayed. Idea for initializing route variables. The node passed to this function is called when the hook is executed. Use ```return``` in Ren'py code to get back to the game.
75+
## ```class AWSWEndingHooks```
76+
This class is responsible for hooking any ending-related parts of the game. Currently implemented functions of this class are listed below.
77+
78+
#### ```ASTHook hookPostTrueEnding(Node node)```
79+
This will jump to ```node``` after the true ending final scene. Use ```return``` in the additive code to end your scene, and the game will continue back to the main menu like normal.
80+
81+
#### ```Node getPostTrueEndingIzumiScene()```
82+
This function will return the node directly after Izumi's "final tear" scene.
83+
84+
#### ```AWSWMenuHooks getEndingPickerMenu()```
85+
This function will return an instance of ```AWSWMenuHooks``` which will allow you to edit the entries in the chapter 5 menu where the player chooses who to go to the fireworks with.
86+
87+
## ```class ASTHook```
88+
The ASTHook class is returned by any of the hooking functions. Its purpose is to all you to modify execution of the game. There are several useful properties on the AST class. First, the ```.next``` member points to the next node that should be executed. This can be set by assigning a node to ```next``` or calling ```chain``` on the class. When the ASTHook node is executed, it checks for a member function called ```hook_func```. If it exists, ```hook_func``` will be executed with the ASTHook class as the first parameter. If ```hook_func``` returns True, the ASTHook will not set the next node. Instead, you must call ```renpy.ast.next_node(Node node)``` manually. This can be used to redirect execution based on circumstances beyond the capabilities of the node alone.
89+
90+
## How to compile like a pro.
91+
Instead of manually creating AST Nodes to insert code into the game, or even clunkily creating entries in the rpy language and then jumping to the snippets with the patcher, you can assemble small(or big!) bits of code *in-line* by abusing the Ren'py AST Parser. This means you can get a list of objects and insert them wherever with very little effort. We use this method internally to create the mod information menu on the main screen. See the core mod or the dev_test mod for further details.
92+
93+
## Debugging
94+
There are several obstacles to developing mods for Ren'py. The first(and biggest) is the fact that the developer has no console to watch for output while running the game! We can fix that by starting AWSW via command line with some switches set. The commands are below.
95+
96+
While in the root directory of the game, run the command for your appropriate operating system:
97+
#### Windows:
98+
```
99+
"lib/windows-i686/python.exe" -EO "Angels with Scaly Wings.py"
100+
```
101+
### Linux x86 (32 bit)
102+
```
103+
./lib/linux-i686/python.exe -EO "Angels with Scaly Wings.py"
104+
```
105+
### Linux x86_64 (64 bit)
106+
```
107+
./lib/linux-x86_64/python.exe -EO "Angels with Scaly Wings.py"
108+
```
109+
110+
Should you print to the console in your code, you may run into an error such as ``` LookupError: unknown encoding: cp437```. This occurs because you're executing a local version of python, which only has utf-8 string encodings loaded in. You can fix this by using ```sprnt``` from ```modlib``` or encoding your string with ```myStr.encode('utf-8')``` before printing.
111+

0 commit comments

Comments
 (0)