Skip to content

A project made with a makeshift text adventure engine built on top of Ren'py.

DaBackpack/Text-py

Repository files navigation

This code is based upon code autogenerated by the Ren'py visual novel engine: https://www.renpy.org/

DISCLAIMER: I can't guarantee that the code in this project is stable or future release-friendly. Even more importantly, I can't
guarantee that this uses good coding style (because it doesn't). Use at your own caution! 

=====PRE-Introduction=====
In this code, there are references to TTF typeface files and sound files which are not included in the code. You can add these yourself or remove the references to them in the code. This is just to demonstrate that normal Ren'py customizations are allowed. 

=====Introduction=====

This is a demonstration of a text adventure engine I built upon the existing Ren'py visual novel engine. No adjustments to Ren'py itself are needed, since all of the adjustments are done through screens and windows. You can use this to build games that resemble ZORK or Colossal Cave Adventure while still having the capacity to use Ren'py utilities and visual effects.

Most of the crucial code is in script.rpy (variable and function declarations) and screens.rpy (window / input configuration). The areas.rpy is a demonstration of how to actually create scenarios and alter the game state.

For a realized demo using this engine, examine the .zip on the top-level directory.

=====Important Variables=====

inputv: String ---- This monitors the verb supplied to the text console. This is always the first term given: "give dog bone" will store "give" into inputv. 
argument: String -- This monitors the argument supplied to the verb in the text console. The string "give dog bone" will result in "dog" being stored into argument. To add more arguments, you may alter the update_input function.
desc: String ------ Because of the flow of execution, the author should not make explicit calls to the Ren'py Say() method (i.e. sarah "Hello!" or $sarah("Hello!")).
    The string assigned to desc will be sent to the engine to output when say() is called. 
append: String ---- This holds a string which will be appended to the string produced by the say() method. You can use this to hold context-insensitive information for the user,
    i.e. printing "You are on the verge of death!" after the player has low hit points in any arbitrary battle. 
room: String ------ Contains the name of the player's current location. This is displayed to the user in the program header. 
hide_val: Boolean - (Default false) If false, displays the input window at the bottom. If true, hides the input window, turning the game into a normal NVL game. 

Optional, but maybe still useful variables:

items: List(String) - Contains strings pertaining to objects owned by the player. 
pickup: List(String) - Contains strings pertaining to objects still available for pickup in the environment. 
expected: List(String) - Contains "acceptable" verbs that may be inputted by the user.


=====Important Functions=====

update_input(string): This is called whenever the user hits an enter key (one used to advance the text). It is fed the contents of the console at that time and stores values into the inputv and argument variables. The author should not manually call this.
    For all intents and purposes, this is the "text parser." You may amend this if you want to have more complex text parsing. 
flush_input(): This wipes the current values of inputv and argument variables. The author should manually call this whenever text is received.
say(): This is the author's interface to the engine. When called, it prints (desc + '\n' + append) to the screen. It then wipes desc and append's current values.

=====Potentially Useful Labels=====

The following are used specifically for this demo and are not married to the engine, but may be useful for certain game scenarios:

wait: This should be called when the inputv variable contains a value not contained in the expected variable. Used to handle malformed input. 
use_failed: This should be called when the user supplies a "use item" command which does not supply a proper "item" argument.

=====Flow of Scripting=====

The author must interface with the engine in a specific way for stability. Check the areas.rpy labels for examples. 
The required flow for each label is as follows:

1) Enter label
2) Assign context-specific variables
3) Assign value to "desc" (usually a description of an environment or a room)
4) Call $say() to provide an initial text dump to the screen
5) Call $flush_input()
6) Enter "While True" loop
7) Check for input using the "e "> [inputv] [argument]{nw}"" command 
8) Check the value of the inputv variable and then direct the user to the next correct label
9) Assign to "desc", "append", and call $say() and $flush_input()
10) Loop back to 7)

It is important that every single possible input is processed or else the execution will be stuck in an infinite loop. Check the areas.rpy file for examples of this.
It is also important that every $say() call is accompanied by a $flush_input() call.
Lastly, only a SINGLE $say() command may be issued during one iteration of the "While True" loop.

In my demo, I treat every "jump"able label as a new room, and every "call"able label as one which does not move the player in the game space (i.e. error messages or help text). You are free to deviate from this though. Just remember that using "jump" breaks from the current loop and enters a new loop, while the "call" function will eventually return to the calling loop. 

=====How it Works=====

(Not important unless you're curious!)

The nvl screen contains three windows: one header window displaying state information (i.e. room and points), one description window (where text is displayed), and the input window (where the user supplies commands).

The execution is as follows:

1) The user type a command and hits the enter key.
2) The input window "listens" for an enter key press and passes information along to the $update_input(string) function.
3) The $update_input(string) function assigns to the inputv and argument variables. 
4) The "While True" loop prints the input to the description window.
5) The manually authored code (in accordance with the ~Flow of Scripting~ section above) attempts to find an action to perform based on the input variables.
6) The program calls $say() and $flush_input() to display a SINGLE message to the screen. 
7) The printed statement "awaits" the user to hit the enter button, like a normal visual novel.
8) Loop back to 1). 

It is important to note that the "enter" key press is overloaded with two functions: one, it controls data flow from the input console to the engine; two, it forces the next line of game text to appear (a la traditional visual novel "enter" key presses). This is why the flow of execution is brittle.

About

A project made with a makeshift text adventure engine built on top of Ren'py.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages