├── .gitignore ├── README.md ├── demo.png ├── game ├── 01example.rpy ├── booleans.rpy ├── classes.rpy ├── conditional.rpy ├── dictionaries.rpy ├── functions.rpy ├── gui.rpy ├── gui │ ├── bar │ │ ├── bottom.png │ │ ├── left.png │ │ ├── right.png │ │ └── top.png │ ├── button │ │ ├── check_foreground.png │ │ ├── check_selected_foreground.png │ │ ├── choice_hover_background.png │ │ ├── choice_idle_background.png │ │ ├── hover_background.png │ │ ├── idle_background.png │ │ ├── quick_hover_background.png │ │ ├── quick_idle_background.png │ │ ├── radio_foreground.png │ │ ├── radio_selected_foreground.png │ │ ├── slot_hover_background.png │ │ └── slot_idle_background.png │ ├── frame.png │ ├── game_menu.png │ ├── main_menu.png │ ├── namebox.png │ ├── notify.png │ ├── nvl.png │ ├── overlay │ │ ├── confirm.png │ │ ├── game_menu.png │ │ └── main_menu.png │ ├── phone │ │ ├── bar │ │ │ ├── bottom.png │ │ │ ├── left.png │ │ │ ├── right.png │ │ │ └── top.png │ │ ├── button │ │ │ ├── check_foreground.png │ │ │ ├── check_selected_foreground.png │ │ │ ├── choice_hover_background.png │ │ │ ├── choice_idle_background.png │ │ │ ├── hover_background.png │ │ │ ├── idle_background.png │ │ │ ├── radio_foreground.png │ │ │ ├── radio_selected_foreground.png │ │ │ ├── slot_hover_background.png │ │ │ └── slot_idle_background.png │ │ ├── nvl.png │ │ ├── overlay │ │ │ ├── game_menu.png │ │ │ └── main_menu.png │ │ ├── scrollbar │ │ │ ├── horizontal_hover_bar.png │ │ │ ├── horizontal_hover_thumb.png │ │ │ ├── horizontal_idle_bar.png │ │ │ ├── horizontal_idle_thumb.png │ │ │ ├── vertical_hover_bar.png │ │ │ ├── vertical_hover_thumb.png │ │ │ ├── vertical_idle_bar.png │ │ │ └── vertical_idle_thumb.png │ │ ├── slider │ │ │ ├── horizontal_hover_bar.png │ │ │ ├── horizontal_hover_thumb.png │ │ │ ├── horizontal_idle_bar.png │ │ │ ├── horizontal_idle_thumb.png │ │ │ ├── vertical_hover_bar.png │ │ │ ├── vertical_hover_thumb.png │ │ │ ├── vertical_idle_bar.png │ │ │ └── vertical_idle_thumb.png │ │ └── textbox.png │ ├── scrollbar │ │ ├── horizontal_hover_bar.png │ │ ├── horizontal_hover_thumb.png │ │ ├── horizontal_idle_bar.png │ │ ├── horizontal_idle_thumb.png │ │ ├── vertical_hover_bar.png │ │ ├── vertical_hover_thumb.png │ │ ├── vertical_idle_bar.png │ │ └── vertical_idle_thumb.png │ ├── skip.png │ ├── slider │ │ ├── horizontal_hover_bar.png │ │ ├── horizontal_hover_thumb.png │ │ ├── horizontal_idle_bar.png │ │ ├── horizontal_idle_thumb.png │ │ ├── vertical_hover_bar.png │ │ ├── vertical_hover_thumb.png │ │ ├── vertical_idle_bar.png │ │ └── vertical_idle_thumb.png │ ├── textbox.png │ └── window_icon.png ├── iterables.rpy ├── keywords.py ├── lists.rpy ├── loop.rpy ├── numbers.rpy ├── options.rpy ├── screens.rpy ├── script.rpy ├── sets.rpy ├── strings.rpy └── tl │ └── None │ └── common.rpym ├── project.json └── python-for-renpy-dev.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS-related files 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Windows-related files 7 | Thumbs.db 8 | Thumbs.db:encryptable 9 | ehthumbs.db 10 | ehthumbs_vista.db 11 | [Dd]esktop.ini 12 | 13 | *.rpyc 14 | *.rpyb 15 | *.rpymc 16 | *.pyc 17 | *.pyo 18 | 19 | *~ 20 | *.bak 21 | 22 | saves 23 | tmp 24 | cache 25 | env 26 | 27 | log.txt 28 | errors.txt 29 | traceback.txt 30 | 31 | styles.txt 32 | 33 | /gui/game/gui 34 | 35 | /android 36 | /build 37 | /dist 38 | /dists 39 | /renpy.app 40 | /jedit 41 | /lint.txt 42 | /renpy.code 43 | /*testing* 44 | /screenshot* 45 | /renpy.exe 46 | /renpy-32.exe 47 | /renpy.sh 48 | /lib 49 | /lib.old 50 | /lib2 51 | /lib3 52 | /doc 53 | /.pydevproject 54 | /.pydevproject.bak 55 | /.project 56 | /.cproject 57 | /.settings 58 | /LICENSE.txt 59 | /templates/english/README.html 60 | /the_question/README.html 61 | /tutorial/README.html 62 | /renpy/angle/*.pyx 63 | /renpy/angle/*.pxd 64 | /renpy-ppc.zip 65 | /module/build 66 | /module/gen* 67 | /editra 68 | /atom 69 | /launcher/game/theme 70 | /launcher/game/script_version.rpy 71 | 72 | /dl 73 | renpy/vc_version.py 74 | .externalToolBuilders 75 | /rapt 76 | /evil 77 | /iaptest 78 | /pygame_sdl2 79 | /renios 80 | /steam_appid.txt 81 | /.coverage 82 | /id 83 | /ai 84 | /interface_7 85 | /htmlcov 86 | /the_question*/.android.json 87 | /WINDOWS.rst 88 | /old 89 | 90 | /*-all/ 91 | /*-win/ 92 | /*-mac/ 93 | /*-linux*/ 94 | /*-dists/ 95 | doc-web 96 | 97 | sphinx/source/inc 98 | sphinx/source/thequestion.rst 99 | tutorial/game/tutorial_director.rpy 100 | launcher/theme 101 | module/emscripten-static/ 102 | web/ 103 | 104 | cubism 105 | glexperiment 106 | live2d 107 | rapt2 108 | rapt3 109 | renios2 110 | renios3 111 | notarized 112 | 113 | CubismSdkForNative-4-*.zip 114 | 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Basics for Ren'Py Developers: A Udemy Course 2 | 3 | This is the course material for my Udemy course, [Python Basics for Ren'Py Developers](https://www.udemy.com/course/python-basics-for-renpy-developers/?referralCode=774C55606994052EBFCB). Even if you aren't taking the course, I hope you will find the content helpful! Check out [my YouTube promotional video](https://www.youtube.com/watch?v=pQcb_pfIbI0) or the free previews on Udemy to learn more. You can also find the material on [itch.io](https://r3dhummingbird.itch.io/python-basics-for-renpy-dev). 4 | 5 | ![Sample Course Material](https://github.com/RuolinZheng08/python-for-renpy-dev/blob/master/demo.png) 6 | 7 | ## Course Intro 8 | 9 | Do you enjoy Visual Novel games? Do you want to add more gameplay elements like mini-games to the traditional Visual Novels? 10 | 11 | This course covers the fundamentals of Python you need to take your Ren'Py game development skills to the next level. Personally, I found those Python concepts essential when I was implementing complex minigames like chess and a rhythm game for my Ren'Py projects. 12 | 13 | In each lecture, we will learn a Python concept using the Python runtime in Google Colab and then see the Python concept in action in Ren'Py scripts. For example, we will see how Python's if-else control flow statements allow us to dynamically show or hide Ren'Py menu choices. 14 | 15 | Topics that we will cover: 16 | 17 | - Variables (strings, numbers, booleans) 18 | - Data Structures (lists, sets, dictionaries) 19 | - Python Control Flow Statements (conditional, loops) 20 | - Advanced Topics (functions, classes) 21 | 22 | No Python experience is necessary. Basic familiarity with Ren'Py is recommended to get the best experience out of this course. Experience with any programming languages will be greatly helpful. 23 | 24 | By the end of this course, you will be able to: 25 | 26 | - Use complex Python data structures in Ren'Py (to create complex components like an inventory system) 27 | - Use Python to organize and simplify your Ren'Py script 28 | 29 | Join me in this course to level up your programming, game development, and Ren'Py skills! 30 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/demo.png -------------------------------------------------------------------------------- /game/01example.rpy: -------------------------------------------------------------------------------- 1 | python early: 2 | 3 | # This maps from example name to the text of a fragment. 4 | examples = { } 5 | 6 | # The size of the example - large or small. 7 | example_size = "small" 8 | 9 | # The location of the example - top or bottom. 10 | example_location = "top" 11 | 12 | # The screen in the last example. 13 | example_screen = None 14 | 15 | # A transition used with examples 16 | example_transition = None 17 | 18 | def reset_example(): 19 | """ 20 | Called to reset the example code to the defaults. 21 | """ 22 | 23 | global example_size 24 | global example_location 25 | global example_screen 26 | 27 | example_size = "small" 28 | example_location = "top" 29 | example_screen = None 30 | 31 | def show_example_screen(name): 32 | global example_screen 33 | example_screen = name 34 | renpy.show_screen(name) 35 | 36 | def hide_example_screen(): 37 | global example_screen 38 | 39 | if example_screen is not None: 40 | renpy.hide_screen(example_screen) 41 | 42 | example_screen = None 43 | 44 | 45 | # Keywords that, at the start of an example block, cause it to be 46 | # outdented 47 | OUTDENT_KEYWORDS = { "define", "default", "image", "screen", "init", "transform", "label", "style" } 48 | 49 | 50 | # This defines the example statement. 51 | # 52 | # The example statement takes: 53 | # * An optional name for the example. 54 | # * An optional hide flag. 55 | # * Optional size flags, large or small. 56 | # * Optional position flags, top or bottom. 57 | # 58 | # The statement defines an example with the name, or an anyonymous name if no 59 | # name is given. When run, the example is displayed if the hide flag is not 60 | # given. 61 | 62 | 63 | def read_example(name, fn, line, outdent): 64 | """ 65 | This reads an example from an example statement, and places it into 66 | the examples dictionary. 67 | """ 68 | 69 | fn = fn.replace("game/", "") 70 | 71 | with renpy.notl_file(fn) as f: 72 | data = f.read().decode("utf-8") 73 | 74 | rawlines = [ i.rstrip() for i in data.split("\n") ] 75 | 76 | lines = [ ] 77 | 78 | base_indent = 0 79 | 80 | while True: 81 | 82 | if line >= len(rawlines): 83 | raise Exception("Example open at end of {}.".format(fn)) 84 | 85 | l = rawlines[line] 86 | line += 1 87 | 88 | if not l: 89 | lines.append(l) 90 | continue 91 | 92 | indent = len(l) - len(l.lstrip()) 93 | 94 | if base_indent == 0: 95 | base_indent = indent 96 | lines.append(l[4:]) 97 | elif indent >= base_indent: 98 | lines.append(l[4:]) 99 | else: 100 | break 101 | 102 | # Determine if the line should be indented. 103 | if outdent == "auto": 104 | 105 | for i in lines: 106 | l = i.strip().split() 107 | if not l: 108 | continue 109 | 110 | if l[0] in OUTDENT_KEYWORDS: 111 | outdent = True 112 | else: 113 | outdent = False 114 | 115 | break 116 | 117 | # Strip indentation. 118 | if outdent: 119 | lines = [ i[base_indent - 4:] for i in lines ] 120 | 121 | if name in examples: 122 | examples[name].append('') 123 | examples[name].extend(lines) 124 | else: 125 | examples[name] = lines 126 | 127 | def parse_example(l): 128 | """ 129 | This parses the example statement. 130 | """ 131 | 132 | # The name of the example. A string, or None if we don't know yet. 133 | name = None 134 | 135 | # Hide, bottom, and small flags. 136 | hide = False 137 | bottom = False 138 | small = False 139 | top = False 140 | large = False 141 | outdent = "auto" 142 | show_screen = True 143 | hide_screen = True 144 | showtrans = False 145 | 146 | while True: 147 | 148 | if l.match(':'): 149 | break 150 | 151 | elif l.keyword('hide'): 152 | hide = True 153 | 154 | elif l.keyword('bottom'): 155 | bottom = True 156 | 157 | elif l.keyword('small'): 158 | small = True 159 | 160 | elif l.keyword('top'): 161 | top = True 162 | 163 | elif l.keyword('large'): 164 | large = True 165 | 166 | elif l.keyword('outdent'): 167 | outdent = True 168 | 169 | elif l.keyword('nooutindent'): 170 | outdent = False 171 | 172 | elif l.keyword("noshow"): 173 | show_screen = False 174 | 175 | elif l.keyword("nohide"): 176 | hide_screen = False 177 | 178 | elif l.keyword("showtrans"): 179 | showtrans = True 180 | 181 | else: 182 | 183 | if name: 184 | l.error('an example may have at most one name') 185 | 186 | name = l.require(l.name) 187 | 188 | l.expect_eol() 189 | 190 | if name is None: 191 | name = "example_{}_{}".format(l.filename, l.number) 192 | 193 | ll = l.subblock_lexer() 194 | ll.advance() 195 | 196 | if ll.keyword('screen'): 197 | screen_name = ll.name() 198 | else: 199 | screen_name = None 200 | 201 | return { 202 | "name" : name, 203 | "names" : [ name ], 204 | "hide" : hide, 205 | "bottom" : bottom, 206 | "small" : small, 207 | "filename" : l.filename, 208 | "number" : l.number, 209 | "top" : top, 210 | "large" : large, 211 | "outdent" : outdent, 212 | "screen_name" : screen_name, 213 | "show_screen" : show_screen, 214 | "hide_screen" : hide_screen, 215 | "showtrans" : showtrans, 216 | } 217 | 218 | def next_example(data, first): 219 | return first 220 | 221 | def execute_example(data): 222 | names = data.get("names", [ ]) 223 | hide = data.get("hide", False) 224 | bottom = data.get("bottom", False) 225 | small = data.get("small", False) 226 | top = data.get("top", False) 227 | large = data.get("large", False) 228 | showtrans = data.get("showtrans", False) 229 | 230 | global example_location 231 | global example_size 232 | 233 | if bottom: 234 | example_location = "bottom" 235 | elif top: 236 | example_location = "top" 237 | 238 | if small: 239 | example_size = "small" 240 | elif large: 241 | example_size = "large" 242 | 243 | if not hide: 244 | renpy.show_screen("example", names, example_size == "small", example_location == "bottom", showtrans=showtrans) 245 | 246 | screen_name = data.get("screen_name", None) 247 | 248 | if screen_name is not None: 249 | if data.get("hide_screen", True): 250 | hide_example_screen() 251 | 252 | if data.get("show_screen", True): 253 | show_example_screen(screen_name) 254 | renpy.with_statement(example_transition) 255 | 256 | def execute_init_example(data): 257 | read_example(data["name"], data["filename"], data["number"], data.get("outdent", "auto")) 258 | 259 | def reachable_example(data, is_reachable, this, next, block): 260 | if is_reachable: 261 | return { this, next, block } 262 | else: 263 | return { True, block } 264 | 265 | renpy.register_statement( 266 | "example", 267 | parse=parse_example, 268 | execute=execute_example, 269 | execute_init=execute_init_example, 270 | next=next_example, 271 | reachable=reachable_example, 272 | block="script") 273 | 274 | 275 | # The show example statement. 276 | 277 | def parse_show_example(l): 278 | 279 | names = [ ] 280 | 281 | bottom = False 282 | small = False 283 | top = False 284 | large = False 285 | showtrans = False 286 | 287 | while not l.eol(): 288 | 289 | if l.keyword('bottom'): 290 | bottom = True 291 | 292 | elif l.keyword('small'): 293 | small = True 294 | 295 | elif l.keyword('top'): 296 | top = True 297 | 298 | elif l.keyword('large'): 299 | large = True 300 | 301 | elif l.keyword('showtrans'): 302 | showtrans = True 303 | 304 | else: 305 | 306 | names.append(l.require(l.name)) 307 | 308 | return { 309 | "names" : names, 310 | "hide" : False, 311 | "bottom" : bottom, 312 | "small" : small, 313 | "top" : top, 314 | "large" : large, 315 | "showtrans" : showtrans, 316 | } 317 | 318 | renpy.register_statement("show example", parse=parse_show_example, execute=execute_example) 319 | 320 | 321 | # The hide example statement. 322 | 323 | def parse_hide_example(l): 324 | 325 | hide_screen = True 326 | 327 | while not l.eol(): 328 | if l.keyword('nohide'): 329 | hide_screen = False 330 | else: 331 | break 332 | 333 | l.expect_eol() 334 | 335 | return { 336 | "hide_screen" : hide_screen, 337 | } 338 | 339 | def execute_hide_example(data): 340 | renpy.hide_screen("example") 341 | 342 | if example_screen and data.get("hide_screen", True) and renpy.get_screen(example_screen): 343 | hide_example_screen() 344 | renpy.with_statement(example_transition) 345 | 346 | renpy.register_statement("hide example", parse=parse_hide_example, execute=execute_hide_example) 347 | 348 | 349 | # A preference that controls if translations are shown. 350 | default persistent.show_translation_marker = False 351 | 352 | init python: 353 | 354 | dialogue_map = { } 355 | 356 | for i in renpy.known_languages(): 357 | dialogue_map[i] = renpy.translation.dialogue.create_dialogue_map(i) 358 | 359 | 360 | import re 361 | import keywords 362 | 363 | KEYWORDS = set(keywords.keywords) 364 | PROPERTIES = set(keywords.properties) 365 | 366 | regex = r"(?P\b(\$|[_a-zA-Z0-9]+)\b)" + \ 367 | r"|(?P\"([^\"]|\\.)*(?#.*)" 369 | 370 | regex = re.compile(regex) 371 | 372 | def quote(s): 373 | s = s.replace("{", "{{") 374 | s = s.replace("[", "[[") 375 | 376 | return s 377 | 378 | def translate(m): 379 | if m.group("string"): 380 | s = eval(m.group(0)) 381 | 382 | if __(s) != s: 383 | s = __(s) 384 | elif _preferences.language: 385 | 386 | dm = dialogue_map[_preferences.language] 387 | 388 | if s in dm: 389 | s = dm[s] 390 | 391 | quote = m.group(0)[0] 392 | s = s.replace("\\", "\\\\") 393 | s = s.replace(quote, "\\" + quote) 394 | s = s.replace("\n", "\\n") 395 | s = quote + s + quote 396 | 397 | return s 398 | 399 | return m.group(0) 400 | 401 | def colorize(m): 402 | if m.group("string"): 403 | return "{color=#060}" + m.group(0) + "{/color}" 404 | 405 | word = m.group("word") 406 | if word: 407 | if word in KEYWORDS: 408 | return "{color=#840}" + m.group(0) + "{/color}" 409 | elif word in PROPERTIES: 410 | return "{color=#048}" + m.group(0) + "{/color}" 411 | else: 412 | return m.group(0) 413 | 414 | if m.group("comment"): 415 | return "{color=#600}" + m.group(0) + "{/color}" 416 | 417 | return m.group(0) 418 | 419 | def clean_example(lines): 420 | rv = list(lines) 421 | 422 | while rv and not rv[0]: 423 | rv.pop(0) 424 | 425 | while rv and not rv[-1]: 426 | rv.pop(-1) 427 | 428 | return rv 429 | 430 | def example_code(blocks, raw=False, showtrans=False): 431 | 432 | if not isinstance(blocks, list): 433 | blocks = [ blocks ] 434 | 435 | 436 | # Collect the examples we use. 437 | lines1 = [ ] 438 | 439 | for i in blocks: 440 | if i not in examples: 441 | lines1.append('Example {} not found.'.format(i)) 442 | else: 443 | lines1.extend(clean_example(examples[i])) 444 | 445 | lines1.append('') 446 | 447 | 448 | # Strip off doubled blank lines. 449 | last_blank = False 450 | lines = [ ] 451 | 452 | for i in lines1: 453 | 454 | if not i and last_blank: 455 | continue 456 | 457 | last_blank = not i 458 | 459 | i = regex.sub(translate, i) 460 | 461 | if not (persistent.show_translation_marker or showtrans): 462 | i = re.sub(r'__?\((".*?")\)', r'\1', i) 463 | i = re.sub(r"__?\(('.*?')\)", r'\1', i) 464 | i = i.replace("!t]", "]") 465 | 466 | if not raw: 467 | i = quote(i) 468 | i = regex.sub(colorize, i) 469 | 470 | lines.append(i) 471 | 472 | while not lines[-1]: 473 | lines.pop() 474 | 475 | # Join them into a single string. 476 | return "\n".join(lines) + "\n " 477 | 478 | class CopyCode(Action): 479 | def __init__(self, s): 480 | self.s = s 481 | 482 | def __call__(self): 483 | import pygame.scrap 484 | pygame.scrap.put(pygame.SCRAP_TEXT, self.s.encode("utf-8")) 485 | renpy.notify(_("Copied the example to the clipboard.")) 486 | 487 | example_transition = dissolve 488 | 489 | import os 490 | SHOW_EXAMPLES = ("RENPY_LESS_EXAMPLES" not in os.environ) 491 | 492 | 493 | transform example_transform(height, ypos): 494 | ypos ypos 495 | yanchor 1.0 496 | xalign 0.5 497 | 498 | on replace: 499 | crop (0, 0, 1280, height) 500 | 501 | on show: 502 | crop (0, 0, 1280, 0) 503 | linear .5 crop (0, 0, 1280, height) 504 | 505 | on hide: 506 | linear .5 crop (0, 0, 1280, 0) 507 | 508 | 509 | screen example(blocks, small=False, bottom=False, showtrans=False): 510 | 511 | zorder 10 512 | 513 | default raw_code = example_code(blocks, raw=True, showtrans=showtrans) 514 | default code = example_code(blocks, showtrans=showtrans) 515 | 516 | if small: 517 | $ height = 80 518 | else: 519 | $ height = 160 520 | 521 | if bottom: 522 | $ ypos = 720 523 | else: 524 | $ ypos = 540 525 | 526 | 527 | if SHOW_EXAMPLES: 528 | 529 | frame: 530 | style "empty" 531 | background "#fffc" 532 | foreground Solid("#aaac", xsize=1, xpos=178) 533 | 534 | xfill True 535 | yfill True 536 | ymaximum height 537 | 538 | at example_transform(height, ypos) 539 | 540 | viewport: 541 | side_xmaximum 1098 542 | side_xpos 180 543 | child_size (2000, 2000) 544 | ymaximum height 545 | draggable True 546 | mousewheel True 547 | scrollbars "vertical" 548 | 549 | vscrollbar_xsize 5 550 | vscrollbar_base_bar "#aaac" 551 | vscrollbar_unscrollable "hide" 552 | 553 | text code: 554 | alt "" 555 | size 16 556 | color "#000" 557 | 558 | textbutton _("copy"): 559 | style "empty" 560 | text_style "quick_button_text" 561 | text_textalign 0.5 562 | text_minwidth 180 563 | 564 | text_size 16 565 | 566 | action CopyCode(raw_code) 567 | 568 | 569 | 570 | 571 | init python hide: 572 | 573 | import os.path 574 | import re 575 | 576 | # A list of files we will be scanning. 577 | files = [ ] 578 | 579 | for i in renpy.list_files(): 580 | if i.endswith(".rpy"): 581 | files.append(i) 582 | 583 | for fn in files: 584 | 585 | try: 586 | with open(os.path.join(renpy.config.gamedir, fn), "r") as f: 587 | lines = f.readlines() 588 | except Exception: 589 | lines = [ ] 590 | 591 | open_examples = set() 592 | 593 | for l in lines: 594 | 595 | l = l.rstrip() 596 | l = l.lstrip("\ufeff") 597 | 598 | m = re.match("\s*#begin (\w+)", l) 599 | if m: 600 | example = m.group(1) 601 | 602 | if example in examples: 603 | raise Exception("Example %r is defined in two places.", example) 604 | 605 | open_examples.add(example) 606 | examples[example] = [ ] 607 | 608 | continue 609 | 610 | m = re.match("\s*#end (\w+)", l) 611 | if m: 612 | example = m.group(1) 613 | 614 | if example not in open_examples: 615 | raise Exception("Example %r is not open.", example) 616 | 617 | open_examples.remove(example) 618 | continue 619 | 620 | for i in open_examples: 621 | examples[i].append(l) 622 | 623 | if open_examples: 624 | raise Exception("Examples %r remain open at the end of %r" % (open_examples, fn)) 625 | 626 | 627 | 628 | init python: 629 | 630 | def lint_stats_callback(): 631 | print("The game contains {} examples.".format(len(examples))) 632 | 633 | config.lint_stats_callbacks.append(lint_stats_callback) 634 | 635 | import base64 636 | 637 | image _finaleimage = im.Data(base64.b64decode(""" 638 | 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 639 | """), "finale.png") 640 | 641 | 642 | image _finale: 643 | "_finaleimage" 644 | yalign 0.3 645 | xanchor 1.0 xpos 0.0 646 | pause 90.0 647 | easein 1.5 xanchor 0.0 xpos .25 648 | pause 3.0 649 | easeout 1.5 xanchor 1.0 xpos 0.0 650 | repeat 651 | -------------------------------------------------------------------------------- /game/booleans.rpy: -------------------------------------------------------------------------------- 1 | #begin booleans 2 | label booleans: 3 | hide screen tutorial 4 | show screen example('booleans') 5 | 6 | python: 7 | has_visited_park = False 8 | has_visited_shop = False 9 | has_visited_beach = False 10 | 11 | label boolean_choices: 12 | menu: 13 | "Where to hang out for the day?" 14 | 15 | # We will cover conditionals `if-else` in later sections 16 | "Park" if not has_visited_park: 17 | e "Let's go to the park!" 18 | $ has_visited_park = True 19 | jump boolean_choices 20 | 21 | "Beach" if not has_visited_beach: 22 | if not has_visited_shop: 23 | e "I'd love to visit the beach, but maybe we can stop by the store to get some ice cream first?" 24 | else: 25 | e "Great! We have everything we need. Let's go to the beach!" 26 | $ has_visited_beach = True 27 | jump boolean_choices 28 | 29 | "Shop" if not has_visited_shop: 30 | e "Let's get some ice cream!" 31 | $ has_visited_shop = True 32 | jump boolean_choices 33 | 34 | jump start 35 | #end booleans -------------------------------------------------------------------------------- /game/classes.rpy: -------------------------------------------------------------------------------- 1 | #begin classes 2 | label classes: 3 | hide screen tutorial 4 | show screen example('classes') 5 | 6 | python: 7 | class Animal(): 8 | def __init__(self, name, speech): 9 | self.name = name 10 | self.speech = speech 11 | self.health = 50 12 | 13 | def greet(self): 14 | # string concatenation 15 | greeting = self.name + ' says ' + self.speech 16 | return greeting 17 | 18 | def add_health(self, value): 19 | self.health += value 20 | # but need to make sure self.health is between 0 and 100 21 | self.health = max(0, self.health) # if smaller than 0, use 0 22 | self.health = min(100, self.health) # if larger than 100, use 100 23 | # no return value 24 | 25 | e "Let's get a pet and give it a name!" 26 | python: 27 | animal_name = renpy.input("What's the pet's name?") 28 | animal_speech = renpy.input("What does it say?") 29 | animal = Animal(animal_name, animal_speech) 30 | greeting = animal.greet() 31 | e "Here is a message from your pet: [greeting]" 32 | e "Your pet currently has health [animal.health]" 33 | $ is_interacting_with_pet = True 34 | 35 | label classes_choices: 36 | menu: 37 | "What to do with the pet?" 38 | 39 | "Feed the pet": 40 | $ animal.add_health(20) 41 | 42 | "Play with the pet": 43 | $ animal.add_health(50) 44 | 45 | "Do nothing": 46 | $ is_interacting_with_pet = False 47 | 48 | if is_interacting_with_pet: 49 | e "Your pet currently has health [animal.health]" 50 | jump classes_choices 51 | else: 52 | jump start 53 | #end classes -------------------------------------------------------------------------------- /game/conditional.rpy: -------------------------------------------------------------------------------- 1 | label conditional: 2 | hide screen tutorial 3 | show screen example('conditional') 4 | 5 | #begin conditional 6 | e "How did you do on the midterm?" 7 | 8 | $ score = 60 9 | 10 | if 90 <= score <= 100: 11 | e "You got an A! Congrats!" 12 | elif 80 <= score <= 89: 13 | e "You got an B. Try harder next time!" 14 | else: 15 | e "You got some other grades. Don't worry." 16 | 17 | $ has_study_buddy = False 18 | menu: 19 | "Would you like to get a study buddy for the final?" 20 | 21 | "Nah I'm fine on my own" if 90 <= score <= 100: 22 | $ has_study_buddy = False 23 | 24 | "Of course!": 25 | $ has_study_buddy = True 26 | 27 | if has_study_buddy: 28 | e "Let's study together for the final!" 29 | else: 30 | e "Looks like you are studying alone for the final." 31 | #end conditional 32 | 33 | jump start -------------------------------------------------------------------------------- /game/dictionaries.rpy: -------------------------------------------------------------------------------- 1 | label dictionaries: 2 | hide screen tutorial 3 | show screen example('dictionaries') 4 | 5 | #begin dictionaries 6 | python: 7 | grades = {'A': [90, 100], 8 | 'B': [80, 89], 9 | 'C': [70, 79], 10 | 'D': [60, 69], 11 | 'F': [0, 59]} 12 | 13 | menu: 14 | "What letter grade did you get on the midterm?" 15 | 16 | "A": 17 | $ score_range = grades['A'] 18 | "B": 19 | $ score_range = grades['B'] 20 | "C": 21 | $ score_range = grades['C'] 22 | "D": 23 | $ score_range = grades['D'] 24 | "F": 25 | $ score_range = grades['F'] 26 | 27 | $ score_lower = score_range[0] 28 | $ score_upper = score_range[1] 29 | e "So you got a score between [score_lower] and [score_upper]." 30 | #end dictionaries 31 | 32 | jump start -------------------------------------------------------------------------------- /game/functions.rpy: -------------------------------------------------------------------------------- 1 | # Using functions really saves us a lot of repeated code 2 | # We have this pretty complex choice scenario coded up in just 50 lines :) 3 | 4 | #begin functions 5 | label functions: 6 | hide screen tutorial 7 | show screen example('functions') 8 | 9 | python: 10 | def make_smoothie(fruit): 11 | procedures = [] 12 | procedures.append('Blending ' + fruit + ' in a blender...') 13 | procedures.append('Adding milk...') 14 | procedures.append('Enjoy a delicious ' + fruit + ' smoothie!\n\n') 15 | return procedures 16 | 17 | def add_to_player_health(player_health, value): 18 | result = player_health + value 19 | # but need to make sure result is between 0 and 100 20 | result = max(0, result) # if smaller than 0, use 0 21 | result = min(100, result) # if larger than 100, use 100 22 | return result 23 | 24 | $ wants_some_smoothie = True 25 | $ player_health = 60 26 | e "Player health is now [player_health]." 27 | 28 | label functions_choices: 29 | menu: 30 | "What kind of smoothie shall we make?" 31 | 32 | "Apple": 33 | $ procedures = make_smoothie('apple') 34 | $ health_increment = 20 35 | 36 | "Dragonfruit": 37 | $ procedures = make_smoothie('dragonfruit') 38 | $ health_increment = 50 39 | 40 | "I've had enough smoothie for the day": 41 | $ wants_some_smoothie = False 42 | 43 | if wants_some_smoothie: 44 | python: 45 | first_procedure = procedures[0] 46 | second_procedure = procedures[1] 47 | third_procedure = procedures[2] 48 | player_health = add_to_player_health(player_health, health_increment) 49 | 50 | e "[first_procedure]" 51 | e "[second_procedure]" 52 | e "[third_procedure]" 53 | e "Player health is now [player_health]." 54 | 55 | jump functions_choices 56 | else: 57 | jump start 58 | #end functions -------------------------------------------------------------------------------- /game/gui.rpy: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## Initialization 3 | ################################################################################ 4 | 5 | ## The init offset statement causes the initialization statements in this file 6 | ## to run before init statements in any other file. 7 | init offset = -2 8 | 9 | ## Calling gui.init resets the styles to sensible default values, and sets the 10 | ## width and height of the game. 11 | init python: 12 | gui.init(1280, 720) 13 | 14 | 15 | 16 | ################################################################################ 17 | ## GUI Configuration Variables 18 | ################################################################################ 19 | 20 | 21 | ## Colors ###################################################################### 22 | ## 23 | ## The colors of text in the interface. 24 | 25 | ## An accent color used throughout the interface to label and highlight text. 26 | define gui.accent_color = u'#0099cc' 27 | 28 | ## The color used for a text button when it is neither selected nor hovered. 29 | define gui.idle_color = u'#888888' 30 | 31 | ## The small color is used for small text, which needs to be brighter/darker to 32 | ## achieve the same effect. 33 | define gui.idle_small_color = u'#aaaaaa' 34 | 35 | ## The color that is used for buttons and bars that are hovered. 36 | define gui.hover_color = u'#66c1e0' 37 | 38 | ## The color used for a text button when it is selected but not focused. A 39 | ## button is selected if it is the current screen or preference value. 40 | define gui.selected_color = u'#ffffff' 41 | 42 | ## The color used for a text button when it cannot be selected. 43 | define gui.insensitive_color = u'#8888887f' 44 | 45 | ## Colors used for the portions of bars that are not filled in. These are not 46 | ## used directly, but are used when re-generating bar image files. 47 | define gui.muted_color = u'#003d51' 48 | define gui.hover_muted_color = u'#005b7a' 49 | 50 | ## The colors used for dialogue and menu choice text. 51 | define gui.text_color = u'#ffffff' 52 | define gui.interface_text_color = u'#ffffff' 53 | 54 | 55 | ## Fonts and Font Sizes ######################################################## 56 | 57 | ## The font used for in-game text. 58 | define gui.text_font = "DejaVuSans.ttf" 59 | 60 | ## The font used for character names. 61 | define gui.name_text_font = "DejaVuSans.ttf" 62 | 63 | ## The font used for out-of-game text. 64 | define gui.interface_text_font = "DejaVuSans.ttf" 65 | 66 | ## The size of normal dialogue text. 67 | define gui.text_size = 22 68 | 69 | ## The size of character names. 70 | define gui.name_text_size = 30 71 | 72 | ## The size of text in the game's user interface. 73 | define gui.interface_text_size = 22 74 | 75 | ## The size of labels in the game's user interface. 76 | define gui.label_text_size = 24 77 | 78 | ## The size of text on the notify screen. 79 | define gui.notify_text_size = 16 80 | 81 | ## The size of the game's title. 82 | define gui.title_text_size = 50 83 | 84 | 85 | ## Main and Game Menus ######################################################### 86 | 87 | ## The images used for the main and game menus. 88 | define gui.main_menu_background = "gui/main_menu.png" 89 | define gui.game_menu_background = "gui/game_menu.png" 90 | 91 | 92 | ## Dialogue #################################################################### 93 | ## 94 | ## These variables control how dialogue is displayed on the screen one line at a 95 | ## time. 96 | 97 | ## The height of the textbox containing dialogue. 98 | define gui.textbox_height = 185 99 | 100 | ## The placement of the textbox vertically on the screen. 0.0 is the top, 0.5 is 101 | ## center, and 1.0 is the bottom. 102 | define gui.textbox_yalign = 1.0 103 | 104 | 105 | ## The placement of the speaking character's name, relative to the textbox. 106 | ## These can be a whole number of pixels from the left or top, or 0.5 to center. 107 | define gui.name_xpos = 240 108 | define gui.name_ypos = 0 109 | 110 | ## The horizontal alignment of the character's name. This can be 0.0 for left- 111 | ## aligned, 0.5 for centered, and 1.0 for right-aligned. 112 | define gui.name_xalign = 0.0 113 | 114 | ## The width, height, and borders of the box containing the character's name, or 115 | ## None to automatically size it. 116 | define gui.namebox_width = None 117 | define gui.namebox_height = None 118 | 119 | ## The borders of the box containing the character's name, in left, top, right, 120 | ## bottom order. 121 | define gui.namebox_borders = Borders(5, 5, 5, 5) 122 | 123 | ## If True, the background of the namebox will be tiled, if False, the 124 | ## background of the namebox will be scaled. 125 | define gui.namebox_tile = False 126 | 127 | 128 | ## The placement of dialogue relative to the textbox. These can be a whole 129 | ## number of pixels relative to the left or top side of the textbox, or 0.5 to 130 | ## center. 131 | define gui.dialogue_xpos = 268 132 | define gui.dialogue_ypos = 50 133 | 134 | ## The maximum width of dialogue text, in pixels. 135 | define gui.dialogue_width = 744 136 | 137 | ## The horizontal alignment of the dialogue text. This can be 0.0 for left- 138 | ## aligned, 0.5 for centered, and 1.0 for right-aligned. 139 | define gui.dialogue_text_xalign = 0.0 140 | 141 | 142 | ## Buttons ##################################################################### 143 | ## 144 | ## These variables, along with the image files in gui/button, control aspects of 145 | ## how buttons are displayed. 146 | 147 | ## The width and height of a button, in pixels. If None, Ren'Py computes a size. 148 | define gui.button_width = None 149 | define gui.button_height = None 150 | 151 | ## The borders on each side of the button, in left, top, right, bottom order. 152 | define gui.button_borders = Borders(4, 4, 4, 4) 153 | 154 | ## If True, the background image will be tiled. If False, the background image 155 | ## will be linearly scaled. 156 | define gui.button_tile = False 157 | 158 | ## The font used by the button. 159 | define gui.button_text_font = gui.interface_text_font 160 | 161 | ## The size of the text used by the button. 162 | define gui.button_text_size = gui.interface_text_size 163 | 164 | ## The color of button text in various states. 165 | define gui.button_text_idle_color = gui.idle_color 166 | define gui.button_text_hover_color = gui.hover_color 167 | define gui.button_text_selected_color = gui.selected_color 168 | define gui.button_text_insensitive_color = gui.insensitive_color 169 | 170 | ## The horizontal alignment of the button text. (0.0 is left, 0.5 is center, 1.0 171 | ## is right). 172 | define gui.button_text_xalign = 0.0 173 | 174 | 175 | ## These variables override settings for different kinds of buttons. Please see 176 | ## the gui documentation for the kinds of buttons available, and what each is 177 | ## used for. 178 | ## 179 | ## These customizations are used by the default interface: 180 | 181 | define gui.radio_button_borders = Borders(18, 4, 4, 4) 182 | 183 | define gui.check_button_borders = Borders(18, 4, 4, 4) 184 | 185 | define gui.confirm_button_text_xalign = 0.5 186 | 187 | define gui.page_button_borders = Borders(10, 4, 10, 4) 188 | 189 | define gui.quick_button_borders = Borders(10, 4, 10, 0) 190 | define gui.quick_button_text_size = 14 191 | define gui.quick_button_text_idle_color = gui.idle_small_color 192 | define gui.quick_button_text_selected_color = gui.accent_color 193 | 194 | ## You can also add your own customizations, by adding properly-named variables. 195 | ## For example, you can uncomment the following line to set the width of a 196 | ## navigation button. 197 | 198 | # define gui.navigation_button_width = 250 199 | 200 | 201 | ## Choice Buttons ############################################################## 202 | ## 203 | ## Choice buttons are used in the in-game menus. 204 | 205 | define gui.choice_button_width = 790 206 | define gui.choice_button_height = None 207 | define gui.choice_button_tile = False 208 | define gui.choice_button_borders = Borders(100, 5, 100, 5) 209 | define gui.choice_button_text_font = gui.text_font 210 | define gui.choice_button_text_size = gui.text_size 211 | define gui.choice_button_text_xalign = 0.5 212 | define gui.choice_button_text_idle_color = "#cccccc" 213 | define gui.choice_button_text_hover_color = "#ffffff" 214 | define gui.choice_button_text_insensitive_color = "#444444" 215 | 216 | 217 | ## File Slot Buttons ########################################################### 218 | ## 219 | ## A file slot button is a special kind of button. It contains a thumbnail 220 | ## image, and text describing the contents of the save slot. A save slot uses 221 | ## image files in gui/button, like the other kinds of buttons. 222 | 223 | ## The save slot button. 224 | define gui.slot_button_width = 276 225 | define gui.slot_button_height = 206 226 | define gui.slot_button_borders = Borders(10, 10, 10, 10) 227 | define gui.slot_button_text_size = 14 228 | define gui.slot_button_text_xalign = 0.5 229 | define gui.slot_button_text_idle_color = gui.idle_small_color 230 | define gui.slot_button_text_selected_idle_color = gui.selected_color 231 | define gui.slot_button_text_selected_hover_color = gui.hover_color 232 | 233 | ## The width and height of thumbnails used by the save slots. 234 | define config.thumbnail_width = 256 235 | define config.thumbnail_height = 144 236 | 237 | ## The number of columns and rows in the grid of save slots. 238 | define gui.file_slot_cols = 3 239 | define gui.file_slot_rows = 2 240 | 241 | 242 | ## Positioning and Spacing ##################################################### 243 | ## 244 | ## These variables control the positioning and spacing of various user interface 245 | ## elements. 246 | 247 | ## The position of the left side of the navigation buttons, relative to the left 248 | ## side of the screen. 249 | define gui.navigation_xpos = 40 250 | 251 | ## The vertical position of the skip indicator. 252 | define gui.skip_ypos = 10 253 | 254 | ## The vertical position of the notify screen. 255 | define gui.notify_ypos = 45 256 | 257 | ## The spacing between menu choices. 258 | define gui.choice_spacing = 22 259 | 260 | ## Buttons in the navigation section of the main and game menus. 261 | define gui.navigation_spacing = 4 262 | 263 | ## Controls the amount of spacing between preferences. 264 | define gui.pref_spacing = 10 265 | 266 | ## Controls the amount of spacing between preference buttons. 267 | define gui.pref_button_spacing = 0 268 | 269 | ## The spacing between file page buttons. 270 | define gui.page_spacing = 0 271 | 272 | ## The spacing between file slots. 273 | define gui.slot_spacing = 10 274 | 275 | ## The position of the main menu text. 276 | define gui.main_menu_text_xalign = 1.0 277 | 278 | 279 | ## Frames ###################################################################### 280 | ## 281 | ## These variables control the look of frames that can contain user interface 282 | ## components when an overlay or window is not present. 283 | 284 | ## Generic frames. 285 | define gui.frame_borders = Borders(4, 4, 4, 4) 286 | 287 | ## The frame that is used as part of the confirm screen. 288 | define gui.confirm_frame_borders = Borders(40, 40, 40, 40) 289 | 290 | ## The frame that is used as part of the skip screen. 291 | define gui.skip_frame_borders = Borders(16, 5, 50, 5) 292 | 293 | ## The frame that is used as part of the notify screen. 294 | define gui.notify_frame_borders = Borders(16, 5, 40, 5) 295 | 296 | ## Should frame backgrounds be tiled? 297 | define gui.frame_tile = False 298 | 299 | 300 | ## Bars, Scrollbars, and Sliders ############################################### 301 | ## 302 | ## These control the look and size of bars, scrollbars, and sliders. 303 | ## 304 | ## The default GUI only uses sliders and vertical scrollbars. All of the other 305 | ## bars are only used in creator-written screens. 306 | 307 | ## The height of horizontal bars, scrollbars, and sliders. The width of vertical 308 | ## bars, scrollbars, and sliders. 309 | define gui.bar_size = 25 310 | define gui.scrollbar_size = 12 311 | define gui.slider_size = 25 312 | 313 | ## True if bar images should be tiled. False if they should be linearly scaled. 314 | define gui.bar_tile = False 315 | define gui.scrollbar_tile = False 316 | define gui.slider_tile = False 317 | 318 | ## Horizontal borders. 319 | define gui.bar_borders = Borders(4, 4, 4, 4) 320 | define gui.scrollbar_borders = Borders(4, 4, 4, 4) 321 | define gui.slider_borders = Borders(4, 4, 4, 4) 322 | 323 | ## Vertical borders. 324 | define gui.vbar_borders = Borders(4, 4, 4, 4) 325 | define gui.vscrollbar_borders = Borders(4, 4, 4, 4) 326 | define gui.vslider_borders = Borders(4, 4, 4, 4) 327 | 328 | ## What to do with unscrollable scrollbars in the gui. "hide" hides them, while 329 | ## None shows them. 330 | define gui.unscrollable = "hide" 331 | 332 | 333 | ## History ##################################################################### 334 | ## 335 | ## The history screen displays dialogue that the player has already dismissed. 336 | 337 | ## The number of blocks of dialogue history Ren'Py will keep. 338 | define config.history_length = 250 339 | 340 | ## The height of a history screen entry, or None to make the height variable at 341 | ## the cost of performance. 342 | define gui.history_height = 140 343 | 344 | ## The position, width, and alignment of the label giving the name of the 345 | ## speaking character. 346 | define gui.history_name_xpos = 155 347 | define gui.history_name_ypos = 0 348 | define gui.history_name_width = 155 349 | define gui.history_name_xalign = 1.0 350 | 351 | ## The position, width, and alignment of the dialogue text. 352 | define gui.history_text_xpos = 170 353 | define gui.history_text_ypos = 2 354 | define gui.history_text_width = 740 355 | define gui.history_text_xalign = 0.0 356 | 357 | 358 | ## NVL-Mode #################################################################### 359 | ## 360 | ## The NVL-mode screen displays the dialogue spoken by NVL-mode characters. 361 | 362 | ## The borders of the background of the NVL-mode background window. 363 | define gui.nvl_borders = Borders(0, 10, 0, 20) 364 | 365 | ## The maximum number of NVL-mode entries Ren'Py will display. When more entries 366 | ## than this are to be show, the oldest entry will be removed. 367 | define gui.nvl_list_length = 6 368 | 369 | ## The height of an NVL-mode entry. Set this to None to have the entries 370 | ## dynamically adjust height. 371 | define gui.nvl_height = 115 372 | 373 | ## The spacing between NVL-mode entries when gui.nvl_height is None, and between 374 | ## NVL-mode entries and an NVL-mode menu. 375 | define gui.nvl_spacing = 10 376 | 377 | ## The position, width, and alignment of the label giving the name of the 378 | ## speaking character. 379 | define gui.nvl_name_xpos = 430 380 | define gui.nvl_name_ypos = 0 381 | define gui.nvl_name_width = 150 382 | define gui.nvl_name_xalign = 1.0 383 | 384 | ## The position, width, and alignment of the dialogue text. 385 | define gui.nvl_text_xpos = 450 386 | define gui.nvl_text_ypos = 8 387 | define gui.nvl_text_width = 590 388 | define gui.nvl_text_xalign = 0.0 389 | 390 | ## The position, width, and alignment of nvl_thought text (the text said by the 391 | ## nvl_narrator character.) 392 | define gui.nvl_thought_xpos = 240 393 | define gui.nvl_thought_ypos = 0 394 | define gui.nvl_thought_width = 780 395 | define gui.nvl_thought_xalign = 0.0 396 | 397 | ## The position of nvl menu_buttons. 398 | define gui.nvl_button_xpos = 450 399 | define gui.nvl_button_xalign = 0.0 400 | 401 | ## Localization ################################################################ 402 | 403 | ## This controls where a line break is permitted. The default is suitable 404 | ## for most languages. A list of available values can be found at https:// 405 | ## www.renpy.org/doc/html/style_properties.html#style-property-language 406 | 407 | define gui.language = "unicode" 408 | 409 | 410 | ################################################################################ 411 | ## Mobile devices 412 | ################################################################################ 413 | 414 | init python: 415 | 416 | ## This increases the size of the quick buttons to make them easier to touch 417 | ## on tablets and phones. 418 | if renpy.variant("touch"): 419 | 420 | gui.quick_button_borders = Borders(40, 14, 40, 0) 421 | 422 | ## This changes the size and spacing of various GUI elements to ensure they 423 | ## are easily visible on phones. 424 | if renpy.variant("small"): 425 | 426 | ## Font sizes. 427 | gui.text_size = 30 428 | gui.name_text_size = 36 429 | gui.notify_text_size = 25 430 | gui.interface_text_size = 30 431 | gui.button_text_size = 30 432 | gui.label_text_size = 34 433 | 434 | ## Adjust the location of the textbox. 435 | gui.textbox_height = 240 436 | gui.name_xpos = 80 437 | gui.dialogue_xpos = 90 438 | gui.dialogue_width = 1100 439 | 440 | ## Change the size and spacing of various things. 441 | gui.slider_size = 36 442 | 443 | gui.choice_button_width = 1240 444 | gui.choice_button_text_size = 30 445 | 446 | gui.navigation_spacing = 20 447 | gui.pref_button_spacing = 10 448 | 449 | gui.history_height = 190 450 | gui.history_text_width = 690 451 | 452 | gui.quick_button_text_size = 20 453 | 454 | ## File button layout. 455 | gui.file_slot_cols = 2 456 | gui.file_slot_rows = 2 457 | 458 | ## NVL-mode. 459 | gui.nvl_height = 170 460 | 461 | gui.nvl_name_width = 305 462 | gui.nvl_name_xpos = 325 463 | 464 | gui.nvl_text_width = 915 465 | gui.nvl_text_xpos = 345 466 | gui.nvl_text_ypos = 5 467 | 468 | gui.nvl_thought_width = 1240 469 | gui.nvl_thought_xpos = 20 470 | 471 | gui.nvl_button_width = 1240 472 | gui.nvl_button_xpos = 20 473 | 474 | 475 | 476 | -------------------------------------------------------------------------------- /game/gui/bar/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/bar/bottom.png -------------------------------------------------------------------------------- /game/gui/bar/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/bar/left.png -------------------------------------------------------------------------------- /game/gui/bar/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/bar/right.png -------------------------------------------------------------------------------- /game/gui/bar/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/bar/top.png -------------------------------------------------------------------------------- /game/gui/button/check_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/check_foreground.png -------------------------------------------------------------------------------- /game/gui/button/check_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/check_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/button/choice_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/choice_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/choice_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/choice_idle_background.png -------------------------------------------------------------------------------- /game/gui/button/hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/hover_background.png -------------------------------------------------------------------------------- /game/gui/button/idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/idle_background.png -------------------------------------------------------------------------------- /game/gui/button/quick_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/quick_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/quick_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/quick_idle_background.png -------------------------------------------------------------------------------- /game/gui/button/radio_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/radio_foreground.png -------------------------------------------------------------------------------- /game/gui/button/radio_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/radio_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/button/slot_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/slot_hover_background.png -------------------------------------------------------------------------------- /game/gui/button/slot_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/button/slot_idle_background.png -------------------------------------------------------------------------------- /game/gui/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/frame.png -------------------------------------------------------------------------------- /game/gui/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/game_menu.png -------------------------------------------------------------------------------- /game/gui/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/main_menu.png -------------------------------------------------------------------------------- /game/gui/namebox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/namebox.png -------------------------------------------------------------------------------- /game/gui/notify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/notify.png -------------------------------------------------------------------------------- /game/gui/nvl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/nvl.png -------------------------------------------------------------------------------- /game/gui/overlay/confirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/overlay/confirm.png -------------------------------------------------------------------------------- /game/gui/overlay/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/overlay/game_menu.png -------------------------------------------------------------------------------- /game/gui/overlay/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/overlay/main_menu.png -------------------------------------------------------------------------------- /game/gui/phone/bar/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/bar/bottom.png -------------------------------------------------------------------------------- /game/gui/phone/bar/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/bar/left.png -------------------------------------------------------------------------------- /game/gui/phone/bar/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/bar/right.png -------------------------------------------------------------------------------- /game/gui/phone/bar/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/bar/top.png -------------------------------------------------------------------------------- /game/gui/phone/button/check_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/check_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/check_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/check_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/choice_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/choice_hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/choice_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/choice_idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/radio_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/radio_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/radio_selected_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/radio_selected_foreground.png -------------------------------------------------------------------------------- /game/gui/phone/button/slot_hover_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/slot_hover_background.png -------------------------------------------------------------------------------- /game/gui/phone/button/slot_idle_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/button/slot_idle_background.png -------------------------------------------------------------------------------- /game/gui/phone/nvl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/nvl.png -------------------------------------------------------------------------------- /game/gui/phone/overlay/game_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/overlay/game_menu.png -------------------------------------------------------------------------------- /game/gui/phone/overlay/main_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/overlay/main_menu.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/scrollbar/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/scrollbar/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/phone/slider/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/slider/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/phone/textbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/phone/textbox.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/scrollbar/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/scrollbar/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/skip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/skip.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/horizontal_hover_bar.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/horizontal_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/horizontal_idle_bar.png -------------------------------------------------------------------------------- /game/gui/slider/horizontal_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/horizontal_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_hover_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/vertical_hover_bar.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_hover_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/vertical_hover_thumb.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_idle_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/vertical_idle_bar.png -------------------------------------------------------------------------------- /game/gui/slider/vertical_idle_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/slider/vertical_idle_thumb.png -------------------------------------------------------------------------------- /game/gui/textbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/textbox.png -------------------------------------------------------------------------------- /game/gui/window_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RuolinZheng08/python-for-renpy-dev/6ae6176f2f858aaa099f39573ebddcefba2d0be4/game/gui/window_icon.png -------------------------------------------------------------------------------- /game/iterables.rpy: -------------------------------------------------------------------------------- 1 | # We are going to cover a little bit of screen language here 2 | 3 | #begin iterables 4 | screen fruit_screen(fruit_list, fruit_set, fruit_colors): 5 | frame: 6 | xsize 640 7 | xalign .5 8 | ysize 300 9 | ypos 30 10 | 11 | add Solid('#000') # black 12 | 13 | hbox spacing 20: 14 | vbox: 15 | text 'Fruit List' 16 | for fruit in fruit_list: 17 | text fruit 18 | 19 | vbox: 20 | text 'Fruit Set' color '#f00' # red text 21 | for fruit in fruit_set: 22 | text fruit color '#f00' # red text 23 | 24 | vbox: 25 | text 'Fruit Inventory' 26 | for fruit in fruit_inventory: # iterate over the keys 27 | # look up the key 28 | $ fruit_quantity = fruit_inventory[fruit] 29 | hbox: 30 | text fruit 31 | null width 10 32 | # fruit_quantity is an integer so we convert it to string 33 | text str(fruit_quantity) color '#f00' # red text 34 | 35 | label iterables: 36 | hide screen tutorial 37 | show screen example('iterables') 38 | 39 | python: 40 | fruit_list = ['apple', 'banana', 'pear', 'orange'] 41 | fruit_set = set(['apple', 'banana', 'pear', 'orange']) 42 | fruit_inventory = {'apple': 2, 43 | 'banana': 0, 44 | 'pear': 3, 45 | 'orange': 1 46 | } 47 | show screen fruit_screen(fruit_list, fruit_set, fruit_inventory) 48 | 49 | e "We have a screen of fruits!" 50 | 51 | hide screen fruit_screen 52 | jump start 53 | #end iterables -------------------------------------------------------------------------------- /game/lists.rpy: -------------------------------------------------------------------------------- 1 | label lists: 2 | hide screen tutorial 3 | show screen example('lists') 4 | 5 | #begin lists 6 | python: 7 | fruits = ['apple', 'banana', 'pear', 'apple'] 8 | veggies = ['carrot', 'cabbage'] 9 | ingredients = [fruits, veggies] 10 | 11 | num_fruits = len(fruits) 12 | num_veggies = len(veggies) 13 | num_ingredient = num_fruits + num_veggies 14 | num_ingredient_types = len(ingredients) 15 | 16 | e "We have [num_ingredient_types] types of ingredients." 17 | e "[num_fruits] fruits and [num_veggies] veggies, so a total of [num_ingredient] ingredients." 18 | 19 | e "Let's get some more veggies. How about celeries?" 20 | # ingredients[1] is the veggies list 21 | python: 22 | ingredients[1].append('celery') 23 | first_veggie_item = veggies[0] # equivalently ingredients[1][0] 24 | second_veggie_item = ingredients[1][1] # just to show you their equivalence 25 | last_veggie_item = veggies[-1] 26 | e "Our veggies are: [first_veggie_item], [second_veggie_item], [last_veggie_item]" 27 | #end lists 28 | 29 | jump start 30 | -------------------------------------------------------------------------------- /game/loop.rpy: -------------------------------------------------------------------------------- 1 | label loop: 2 | hide screen tutorial 3 | show screen example('loop') 4 | 5 | #begin loop 6 | $ countdown = 5 7 | e "Let's start the countdown from [countdown]." 8 | 9 | while countdown > 0: 10 | e "Countdown value: [countdown]" 11 | $ countdown -= 1 12 | 13 | e "The end value of countdown is [countdown]" 14 | #end loop 15 | 16 | jump start -------------------------------------------------------------------------------- /game/numbers.rpy: -------------------------------------------------------------------------------- 1 | label numbers: 2 | hide screen tutorial 3 | show screen example('numbers') 4 | 5 | #begin numbers 6 | $ player_health = 60 7 | e "Player health is currently: [player_health]" 8 | menu: 9 | "What to have for dinner?" 10 | 11 | "Pizza": 12 | $ player_health += 10 13 | e "Nice! I love pizza." 14 | 15 | "Veggies": 16 | $ player_health += 50 17 | # but we don't want player_health to exceed 100 18 | $ player_health = min(player_health, 100) 19 | e "Veggies? That's a super healthy choice!" 20 | 21 | e "Player health after dinner is: [player_health]" 22 | #end numbers 23 | 24 | jump start -------------------------------------------------------------------------------- /game/options.rpy: -------------------------------------------------------------------------------- 1 | ## This file contains options that can be changed to customize your game. 2 | ## 3 | ## Lines beginning with two '#' marks are comments, and you shouldn't uncomment 4 | ## them. Lines beginning with a single '#' mark are commented-out code, and you 5 | ## may want to uncomment them when appropriate. 6 | 7 | 8 | ## Basics ###################################################################### 9 | 10 | ## A human-readable name of the game. This is used to set the default window 11 | ## title, and shows up in the interface and error reports. 12 | ## 13 | ## The _() surrounding the string marks it as eligible for translation. 14 | 15 | define config.name = _("Python For RenPy Dev") 16 | 17 | 18 | ## Determines if the title given above is shown on the main menu screen. Set 19 | ## this to False to hide the title. 20 | 21 | define gui.show_name = True 22 | 23 | 24 | ## The version of the game. 25 | 26 | define config.version = "1.0" 27 | 28 | 29 | ## Text that is placed on the game's about screen. Place the text between the 30 | ## triple-quotes, and leave a blank line between paragraphs. 31 | 32 | define gui.about = _p(""" 33 | """) 34 | 35 | 36 | ## A short name for the game used for executables and directories in the built 37 | ## distribution. This must be ASCII-only, and must not contain spaces, colons, 38 | ## or semicolons. 39 | 40 | define build.name = "PythonForRenPyDev" 41 | 42 | 43 | ## Sounds and music ############################################################ 44 | 45 | ## These three variables control which mixers are shown to the player by 46 | ## default. Setting one of these to False will hide the appropriate mixer. 47 | 48 | define config.has_sound = True 49 | define config.has_music = True 50 | define config.has_voice = True 51 | 52 | 53 | ## To allow the user to play a test sound on the sound or voice channel, 54 | ## uncomment a line below and use it to set a sample sound to play. 55 | 56 | # define config.sample_sound = "sample-sound.ogg" 57 | # define config.sample_voice = "sample-voice.ogg" 58 | 59 | 60 | ## Uncomment the following line to set an audio file that will be played while 61 | ## the player is at the main menu. This file will continue playing into the 62 | ## game, until it is stopped or another file is played. 63 | 64 | # define config.main_menu_music = "main-menu-theme.ogg" 65 | 66 | 67 | ## Transitions ################################################################# 68 | ## 69 | ## These variables set transitions that are used when certain events occur. 70 | ## Each variable should be set to a transition, or None to indicate that no 71 | ## transition should be used. 72 | 73 | ## Entering or exiting the game menu. 74 | 75 | define config.enter_transition = dissolve 76 | define config.exit_transition = dissolve 77 | 78 | 79 | ## Between screens of the game menu. 80 | 81 | define config.intra_transition = dissolve 82 | 83 | 84 | ## A transition that is used after a game has been loaded. 85 | 86 | define config.after_load_transition = None 87 | 88 | 89 | ## Used when entering the main menu after the game has ended. 90 | 91 | define config.end_game_transition = None 92 | 93 | 94 | ## A variable to set the transition used when the game starts does not exist. 95 | ## Instead, use a with statement after showing the initial scene. 96 | 97 | 98 | ## Window management ########################################################### 99 | ## 100 | ## This controls when the dialogue window is displayed. If "show", it is always 101 | ## displayed. If "hide", it is only displayed when dialogue is present. If 102 | ## "auto", the window is hidden before scene statements and shown again once 103 | ## dialogue is displayed. 104 | ## 105 | ## After the game has started, this can be changed with the "window show", 106 | ## "window hide", and "window auto" statements. 107 | 108 | define config.window = "auto" 109 | 110 | 111 | ## Transitions used to show and hide the dialogue window 112 | 113 | define config.window_show_transition = Dissolve(.2) 114 | define config.window_hide_transition = Dissolve(.2) 115 | 116 | 117 | ## Preference defaults ######################################################### 118 | 119 | ## Controls the default text speed. The default, 0, is infinite, while any other 120 | ## number is the number of characters per second to type out. 121 | 122 | default preferences.text_cps = 0 123 | 124 | 125 | ## The default auto-forward delay. Larger numbers lead to longer waits, with 0 126 | ## to 30 being the valid range. 127 | 128 | default preferences.afm_time = 15 129 | 130 | 131 | ## Save directory ############################################################## 132 | ## 133 | ## Controls the platform-specific place Ren'Py will place the save files for 134 | ## this game. The save files will be placed in: 135 | ## 136 | ## Windows: %APPDATA\RenPy\ 137 | ## 138 | ## Macintosh: $HOME/Library/RenPy/ 139 | ## 140 | ## Linux: $HOME/.renpy/ 141 | ## 142 | ## This generally should not be changed, and if it is, should always be a 143 | ## literal string, not an expression. 144 | 145 | define config.save_directory = "PythonForRenPyDev-1623695227" 146 | 147 | 148 | ## Icon ######################################################################## 149 | ## 150 | ## The icon displayed on the taskbar or dock. 151 | 152 | define config.window_icon = "gui/window_icon.png" 153 | 154 | 155 | ## Build configuration ######################################################### 156 | ## 157 | ## This section controls how Ren'Py turns your project into distribution files. 158 | 159 | init python: 160 | 161 | ## The following functions take file patterns. File patterns are case- 162 | ## insensitive, and matched against the path relative to the base directory, 163 | ## with and without a leading /. If multiple patterns match, the first is 164 | ## used. 165 | ## 166 | ## In a pattern: 167 | ## 168 | ## / is the directory separator. 169 | ## 170 | ## * matches all characters, except the directory separator. 171 | ## 172 | ## ** matches all characters, including the directory separator. 173 | ## 174 | ## For example, "*.txt" matches txt files in the base directory, "game/ 175 | ## **.ogg" matches ogg files in the game directory or any of its 176 | ## subdirectories, and "**.psd" matches psd files anywhere in the project. 177 | 178 | ## Classify files as None to exclude them from the built distributions. 179 | 180 | build.classify('**~', None) 181 | build.classify('**.bak', None) 182 | build.classify('**/.**', None) 183 | build.classify('**/#**', None) 184 | build.classify('**/thumbs.db', None) 185 | 186 | ## To archive files, classify them as 'archive'. 187 | 188 | # build.classify('game/**.png', 'archive') 189 | # build.classify('game/**.jpg', 'archive') 190 | 191 | ## Files matching documentation patterns are duplicated in a mac app build, 192 | ## so they appear in both the app and the zip file. 193 | 194 | build.documentation('*.html') 195 | build.documentation('*.txt') 196 | 197 | 198 | ## A Google Play license key is required to download expansion files and perform 199 | ## in-app purchases. It can be found on the "Services & APIs" page of the Google 200 | ## Play developer console. 201 | 202 | # define build.google_play_key = "..." 203 | 204 | 205 | ## The username and project name associated with an itch.io project, separated 206 | ## by a slash. 207 | 208 | # define build.itch_project = "renpytom/test-project" 209 | -------------------------------------------------------------------------------- /game/screens.rpy: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | ## Initialization 3 | ################################################################################ 4 | 5 | init offset = -1 6 | 7 | 8 | ################################################################################ 9 | ## Styles 10 | ################################################################################ 11 | 12 | style default: 13 | properties gui.text_properties() 14 | language gui.language 15 | 16 | style input: 17 | properties gui.text_properties("input", accent=True) 18 | adjust_spacing False 19 | 20 | style hyperlink_text: 21 | properties gui.text_properties("hyperlink", accent=True) 22 | hover_underline True 23 | 24 | style gui_text: 25 | properties gui.text_properties("interface") 26 | 27 | 28 | style button: 29 | properties gui.button_properties("button") 30 | 31 | style button_text is gui_text: 32 | properties gui.text_properties("button") 33 | yalign 0.5 34 | 35 | 36 | style label_text is gui_text: 37 | properties gui.text_properties("label", accent=True) 38 | 39 | style prompt_text is gui_text: 40 | properties gui.text_properties("prompt") 41 | 42 | 43 | style bar: 44 | ysize gui.bar_size 45 | left_bar Frame("gui/bar/left.png", gui.bar_borders, tile=gui.bar_tile) 46 | right_bar Frame("gui/bar/right.png", gui.bar_borders, tile=gui.bar_tile) 47 | 48 | style vbar: 49 | xsize gui.bar_size 50 | top_bar Frame("gui/bar/top.png", gui.vbar_borders, tile=gui.bar_tile) 51 | bottom_bar Frame("gui/bar/bottom.png", gui.vbar_borders, tile=gui.bar_tile) 52 | 53 | style scrollbar: 54 | ysize gui.scrollbar_size 55 | base_bar Frame("gui/scrollbar/horizontal_[prefix_]bar.png", gui.scrollbar_borders, tile=gui.scrollbar_tile) 56 | thumb Frame("gui/scrollbar/horizontal_[prefix_]thumb.png", gui.scrollbar_borders, tile=gui.scrollbar_tile) 57 | 58 | style vscrollbar: 59 | xsize gui.scrollbar_size 60 | base_bar Frame("gui/scrollbar/vertical_[prefix_]bar.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile) 61 | thumb Frame("gui/scrollbar/vertical_[prefix_]thumb.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile) 62 | 63 | style slider: 64 | ysize gui.slider_size 65 | base_bar Frame("gui/slider/horizontal_[prefix_]bar.png", gui.slider_borders, tile=gui.slider_tile) 66 | thumb "gui/slider/horizontal_[prefix_]thumb.png" 67 | 68 | style vslider: 69 | xsize gui.slider_size 70 | base_bar Frame("gui/slider/vertical_[prefix_]bar.png", gui.vslider_borders, tile=gui.slider_tile) 71 | thumb "gui/slider/vertical_[prefix_]thumb.png" 72 | 73 | 74 | style frame: 75 | padding gui.frame_borders.padding 76 | background Frame("gui/frame.png", gui.frame_borders, tile=gui.frame_tile) 77 | 78 | 79 | 80 | ################################################################################ 81 | ## In-game screens 82 | ################################################################################ 83 | 84 | 85 | ## Say screen ################################################################## 86 | ## 87 | ## The say screen is used to display dialogue to the player. It takes two 88 | ## parameters, who and what, which are the name of the speaking character and 89 | ## the text to be displayed, respectively. (The who parameter can be None if no 90 | ## name is given.) 91 | ## 92 | ## This screen must create a text displayable with id "what", as Ren'Py uses 93 | ## this to manage text display. It can also create displayables with id "who" 94 | ## and id "window" to apply style properties. 95 | ## 96 | ## https://www.renpy.org/doc/html/screen_special.html#say 97 | 98 | screen say(who, what): 99 | style_prefix "say" 100 | 101 | window: 102 | id "window" 103 | 104 | if who is not None: 105 | 106 | window: 107 | id "namebox" 108 | style "namebox" 109 | text who id "who" 110 | 111 | text what id "what" 112 | 113 | 114 | ## If there's a side image, display it above the text. Do not display on the 115 | ## phone variant - there's no room. 116 | if not renpy.variant("small"): 117 | add SideImage() xalign 0.0 yalign 1.0 118 | 119 | 120 | ## Make the namebox available for styling through the Character object. 121 | init python: 122 | config.character_id_prefixes.append('namebox') 123 | 124 | style window is default 125 | style say_label is default 126 | style say_dialogue is default 127 | style say_thought is say_dialogue 128 | 129 | style namebox is default 130 | style namebox_label is say_label 131 | 132 | 133 | style window: 134 | xalign 0.5 135 | xfill True 136 | yalign gui.textbox_yalign 137 | ysize gui.textbox_height 138 | 139 | background Image("gui/textbox.png", xalign=0.5, yalign=1.0) 140 | 141 | style namebox: 142 | xpos gui.name_xpos 143 | xanchor gui.name_xalign 144 | xsize gui.namebox_width 145 | ypos gui.name_ypos 146 | ysize gui.namebox_height 147 | 148 | background Frame("gui/namebox.png", gui.namebox_borders, tile=gui.namebox_tile, xalign=gui.name_xalign) 149 | padding gui.namebox_borders.padding 150 | 151 | style say_label: 152 | properties gui.text_properties("name", accent=True) 153 | xalign gui.name_xalign 154 | yalign 0.5 155 | 156 | style say_dialogue: 157 | properties gui.text_properties("dialogue") 158 | 159 | xpos gui.dialogue_xpos 160 | xsize gui.dialogue_width 161 | ypos gui.dialogue_ypos 162 | 163 | 164 | ## Input screen ################################################################ 165 | ## 166 | ## This screen is used to display renpy.input. The prompt parameter is used to 167 | ## pass a text prompt in. 168 | ## 169 | ## This screen must create an input displayable with id "input" to accept the 170 | ## various input parameters. 171 | ## 172 | ## https://www.renpy.org/doc/html/screen_special.html#input 173 | 174 | screen input(prompt): 175 | style_prefix "input" 176 | 177 | window: 178 | 179 | vbox: 180 | xalign gui.dialogue_text_xalign 181 | xpos gui.dialogue_xpos 182 | xsize gui.dialogue_width 183 | ypos gui.dialogue_ypos 184 | 185 | text prompt style "input_prompt" 186 | input id "input" 187 | 188 | style input_prompt is default 189 | 190 | style input_prompt: 191 | xalign gui.dialogue_text_xalign 192 | properties gui.text_properties("input_prompt") 193 | 194 | style input: 195 | xalign gui.dialogue_text_xalign 196 | xmaximum gui.dialogue_width 197 | 198 | 199 | ## Choice screen ############################################################### 200 | ## 201 | ## This screen is used to display the in-game choices presented by the menu 202 | ## statement. The one parameter, items, is a list of objects, each with caption 203 | ## and action fields. 204 | ## 205 | ## https://www.renpy.org/doc/html/screen_special.html#choice 206 | 207 | screen choice(items): 208 | style_prefix "choice" 209 | 210 | vbox: 211 | for i in items: 212 | textbutton i.caption action i.action 213 | 214 | 215 | ## When this is true, menu captions will be spoken by the narrator. When false, 216 | ## menu captions will be displayed as empty buttons. 217 | define config.narrator_menu = True 218 | 219 | 220 | style choice_vbox is vbox 221 | style choice_button is button 222 | style choice_button_text is button_text 223 | 224 | style choice_vbox: 225 | xalign 0.5 226 | ypos 270 227 | yanchor 0.5 228 | 229 | spacing gui.choice_spacing 230 | 231 | style choice_button is default: 232 | properties gui.button_properties("choice_button") 233 | 234 | style choice_button_text is default: 235 | properties gui.button_text_properties("choice_button") 236 | 237 | 238 | ## Quick Menu screen ########################################################### 239 | ## 240 | ## The quick menu is displayed in-game to provide easy access to the out-of-game 241 | ## menus. 242 | 243 | screen quick_menu(): 244 | 245 | ## Ensure this appears on top of other screens. 246 | zorder 100 247 | 248 | if quick_menu: 249 | 250 | hbox: 251 | style_prefix "quick" 252 | 253 | xalign 0.5 254 | yalign 1.0 255 | 256 | textbutton _("Back") action Rollback() 257 | textbutton _("History") action ShowMenu('history') 258 | textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True) 259 | textbutton _("Auto") action Preference("auto-forward", "toggle") 260 | textbutton _("Save") action ShowMenu('save') 261 | textbutton _("Q.Save") action QuickSave() 262 | textbutton _("Q.Load") action QuickLoad() 263 | textbutton _("Prefs") action ShowMenu('preferences') 264 | 265 | 266 | ## This code ensures that the quick_menu screen is displayed in-game, whenever 267 | ## the player has not explicitly hidden the interface. 268 | init python: 269 | config.overlay_screens.append("quick_menu") 270 | 271 | default quick_menu = True 272 | 273 | style quick_button is default 274 | style quick_button_text is button_text 275 | 276 | style quick_button: 277 | properties gui.button_properties("quick_button") 278 | 279 | style quick_button_text: 280 | properties gui.button_text_properties("quick_button") 281 | 282 | 283 | ################################################################################ 284 | ## Main and Game Menu Screens 285 | ################################################################################ 286 | 287 | ## Navigation screen ########################################################### 288 | ## 289 | ## This screen is included in the main and game menus, and provides navigation 290 | ## to other menus, and to start the game. 291 | 292 | screen navigation(): 293 | 294 | vbox: 295 | style_prefix "navigation" 296 | 297 | xpos gui.navigation_xpos 298 | yalign 0.5 299 | 300 | spacing gui.navigation_spacing 301 | 302 | if main_menu: 303 | 304 | textbutton _("Start") action Start() 305 | 306 | else: 307 | 308 | textbutton _("History") action ShowMenu("history") 309 | 310 | textbutton _("Save") action ShowMenu("save") 311 | 312 | textbutton _("Load") action ShowMenu("load") 313 | 314 | textbutton _("Preferences") action ShowMenu("preferences") 315 | 316 | if _in_replay: 317 | 318 | textbutton _("End Replay") action EndReplay(confirm=True) 319 | 320 | elif not main_menu: 321 | 322 | textbutton _("Main Menu") action MainMenu() 323 | 324 | textbutton _("About") action ShowMenu("about") 325 | 326 | if renpy.variant("pc") or (renpy.variant("web") and not renpy.variant("mobile")): 327 | 328 | ## Help isn't necessary or relevant to mobile devices. 329 | textbutton _("Help") action ShowMenu("help") 330 | 331 | if renpy.variant("pc"): 332 | 333 | ## The quit button is banned on iOS and unnecessary on Android and 334 | ## Web. 335 | textbutton _("Quit") action Quit(confirm=not main_menu) 336 | 337 | 338 | style navigation_button is gui_button 339 | style navigation_button_text is gui_button_text 340 | 341 | style navigation_button: 342 | size_group "navigation" 343 | properties gui.button_properties("navigation_button") 344 | 345 | style navigation_button_text: 346 | properties gui.button_text_properties("navigation_button") 347 | 348 | 349 | ## Main Menu screen ############################################################ 350 | ## 351 | ## Used to display the main menu when Ren'Py starts. 352 | ## 353 | ## https://www.renpy.org/doc/html/screen_special.html#main-menu 354 | 355 | screen main_menu(): 356 | 357 | ## This ensures that any other menu screen is replaced. 358 | tag menu 359 | 360 | add gui.main_menu_background 361 | 362 | ## This empty frame darkens the main menu. 363 | frame: 364 | style "main_menu_frame" 365 | 366 | ## The use statement includes another screen inside this one. The actual 367 | ## contents of the main menu are in the navigation screen. 368 | use navigation 369 | 370 | if gui.show_name: 371 | 372 | vbox: 373 | style "main_menu_vbox" 374 | 375 | text "[config.name!t]": 376 | style "main_menu_title" 377 | 378 | text "[config.version]": 379 | style "main_menu_version" 380 | 381 | 382 | style main_menu_frame is empty 383 | style main_menu_vbox is vbox 384 | style main_menu_text is gui_text 385 | style main_menu_title is main_menu_text 386 | style main_menu_version is main_menu_text 387 | 388 | style main_menu_frame: 389 | xsize 280 390 | yfill True 391 | 392 | background "gui/overlay/main_menu.png" 393 | 394 | style main_menu_vbox: 395 | xalign 1.0 396 | xoffset -20 397 | xmaximum 800 398 | yalign 1.0 399 | yoffset -20 400 | 401 | style main_menu_text: 402 | properties gui.text_properties("main_menu", accent=True) 403 | 404 | style main_menu_title: 405 | properties gui.text_properties("title") 406 | 407 | style main_menu_version: 408 | properties gui.text_properties("version") 409 | 410 | 411 | ## Game Menu screen ############################################################ 412 | ## 413 | ## This lays out the basic common structure of a game menu screen. It's called 414 | ## with the screen title, and displays the background, title, and navigation. 415 | ## 416 | ## The scroll parameter can be None, or one of "viewport" or "vpgrid". When 417 | ## this screen is intended to be used with one or more children, which are 418 | ## transcluded (placed) inside it. 419 | 420 | screen game_menu(title, scroll=None, yinitial=0.0): 421 | 422 | style_prefix "game_menu" 423 | 424 | if main_menu: 425 | add gui.main_menu_background 426 | else: 427 | add gui.game_menu_background 428 | 429 | frame: 430 | style "game_menu_outer_frame" 431 | 432 | hbox: 433 | 434 | ## Reserve space for the navigation section. 435 | frame: 436 | style "game_menu_navigation_frame" 437 | 438 | frame: 439 | style "game_menu_content_frame" 440 | 441 | if scroll == "viewport": 442 | 443 | viewport: 444 | yinitial yinitial 445 | scrollbars "vertical" 446 | mousewheel True 447 | draggable True 448 | pagekeys True 449 | 450 | side_yfill True 451 | 452 | vbox: 453 | transclude 454 | 455 | elif scroll == "vpgrid": 456 | 457 | vpgrid: 458 | cols 1 459 | yinitial yinitial 460 | 461 | scrollbars "vertical" 462 | mousewheel True 463 | draggable True 464 | pagekeys True 465 | 466 | side_yfill True 467 | 468 | transclude 469 | 470 | else: 471 | 472 | transclude 473 | 474 | use navigation 475 | 476 | textbutton _("Return"): 477 | style "return_button" 478 | 479 | action Return() 480 | 481 | label title 482 | 483 | if main_menu: 484 | key "game_menu" action ShowMenu("main_menu") 485 | 486 | 487 | style game_menu_outer_frame is empty 488 | style game_menu_navigation_frame is empty 489 | style game_menu_content_frame is empty 490 | style game_menu_viewport is gui_viewport 491 | style game_menu_side is gui_side 492 | style game_menu_scrollbar is gui_vscrollbar 493 | 494 | style game_menu_label is gui_label 495 | style game_menu_label_text is gui_label_text 496 | 497 | style return_button is navigation_button 498 | style return_button_text is navigation_button_text 499 | 500 | style game_menu_outer_frame: 501 | bottom_padding 30 502 | top_padding 120 503 | 504 | background "gui/overlay/game_menu.png" 505 | 506 | style game_menu_navigation_frame: 507 | xsize 280 508 | yfill True 509 | 510 | style game_menu_content_frame: 511 | left_margin 40 512 | right_margin 20 513 | top_margin 10 514 | 515 | style game_menu_viewport: 516 | xsize 920 517 | 518 | style game_menu_vscrollbar: 519 | unscrollable gui.unscrollable 520 | 521 | style game_menu_side: 522 | spacing 10 523 | 524 | style game_menu_label: 525 | xpos 50 526 | ysize 120 527 | 528 | style game_menu_label_text: 529 | size gui.title_text_size 530 | color gui.accent_color 531 | yalign 0.5 532 | 533 | style return_button: 534 | xpos gui.navigation_xpos 535 | yalign 1.0 536 | yoffset -30 537 | 538 | 539 | ## About screen ################################################################ 540 | ## 541 | ## This screen gives credit and copyright information about the game and Ren'Py. 542 | ## 543 | ## There's nothing special about this screen, and hence it also serves as an 544 | ## example of how to make a custom screen. 545 | 546 | screen about(): 547 | 548 | tag menu 549 | 550 | ## This use statement includes the game_menu screen inside this one. The 551 | ## vbox child is then included inside the viewport inside the game_menu 552 | ## screen. 553 | use game_menu(_("About"), scroll="viewport"): 554 | 555 | style_prefix "about" 556 | 557 | vbox: 558 | 559 | label "[config.name!t]" 560 | text _("Version [config.version!t]\n") 561 | 562 | ## gui.about is usually set in options.rpy. 563 | if gui.about: 564 | text "[gui.about!t]\n" 565 | 566 | text _("Made with {a=https://www.renpy.org/}Ren'Py{/a} [renpy.version_only].\n\n[renpy.license!t]") 567 | 568 | 569 | style about_label is gui_label 570 | style about_label_text is gui_label_text 571 | style about_text is gui_text 572 | 573 | style about_label_text: 574 | size gui.label_text_size 575 | 576 | 577 | ## Load and Save screens ####################################################### 578 | ## 579 | ## These screens are responsible for letting the player save the game and load 580 | ## it again. Since they share nearly everything in common, both are implemented 581 | ## in terms of a third screen, file_slots. 582 | ## 583 | ## https://www.renpy.org/doc/html/screen_special.html#save https:// 584 | ## www.renpy.org/doc/html/screen_special.html#load 585 | 586 | screen save(): 587 | 588 | tag menu 589 | 590 | use file_slots(_("Save")) 591 | 592 | 593 | screen load(): 594 | 595 | tag menu 596 | 597 | use file_slots(_("Load")) 598 | 599 | 600 | screen file_slots(title): 601 | 602 | default page_name_value = FilePageNameInputValue(pattern=_("Page {}"), auto=_("Automatic saves"), quick=_("Quick saves")) 603 | 604 | use game_menu(title): 605 | 606 | fixed: 607 | 608 | ## This ensures the input will get the enter event before any of the 609 | ## buttons do. 610 | order_reverse True 611 | 612 | ## The page name, which can be edited by clicking on a button. 613 | button: 614 | style "page_label" 615 | 616 | key_events True 617 | xalign 0.5 618 | action page_name_value.Toggle() 619 | 620 | input: 621 | style "page_label_text" 622 | value page_name_value 623 | 624 | ## The grid of file slots. 625 | grid gui.file_slot_cols gui.file_slot_rows: 626 | style_prefix "slot" 627 | 628 | xalign 0.5 629 | yalign 0.5 630 | 631 | spacing gui.slot_spacing 632 | 633 | for i in range(gui.file_slot_cols * gui.file_slot_rows): 634 | 635 | $ slot = i + 1 636 | 637 | button: 638 | action FileAction(slot) 639 | 640 | has vbox 641 | 642 | add FileScreenshot(slot) xalign 0.5 643 | 644 | text FileTime(slot, format=_("{#file_time}%A, %B %d %Y, %H:%M"), empty=_("empty slot")): 645 | style "slot_time_text" 646 | 647 | text FileSaveName(slot): 648 | style "slot_name_text" 649 | 650 | key "save_delete" action FileDelete(slot) 651 | 652 | ## Buttons to access other pages. 653 | hbox: 654 | style_prefix "page" 655 | 656 | xalign 0.5 657 | yalign 1.0 658 | 659 | spacing gui.page_spacing 660 | 661 | textbutton _("<") action FilePagePrevious() 662 | 663 | if config.has_autosave: 664 | textbutton _("{#auto_page}A") action FilePage("auto") 665 | 666 | if config.has_quicksave: 667 | textbutton _("{#quick_page}Q") action FilePage("quick") 668 | 669 | ## range(1, 10) gives the numbers from 1 to 9. 670 | for page in range(1, 10): 671 | textbutton "[page]" action FilePage(page) 672 | 673 | textbutton _(">") action FilePageNext() 674 | 675 | 676 | style page_label is gui_label 677 | style page_label_text is gui_label_text 678 | style page_button is gui_button 679 | style page_button_text is gui_button_text 680 | 681 | style slot_button is gui_button 682 | style slot_button_text is gui_button_text 683 | style slot_time_text is slot_button_text 684 | style slot_name_text is slot_button_text 685 | 686 | style page_label: 687 | xpadding 50 688 | ypadding 3 689 | 690 | style page_label_text: 691 | text_align 0.5 692 | layout "subtitle" 693 | hover_color gui.hover_color 694 | 695 | style page_button: 696 | properties gui.button_properties("page_button") 697 | 698 | style page_button_text: 699 | properties gui.button_text_properties("page_button") 700 | 701 | style slot_button: 702 | properties gui.button_properties("slot_button") 703 | 704 | style slot_button_text: 705 | properties gui.button_text_properties("slot_button") 706 | 707 | 708 | ## Preferences screen ########################################################## 709 | ## 710 | ## The preferences screen allows the player to configure the game to better suit 711 | ## themselves. 712 | ## 713 | ## https://www.renpy.org/doc/html/screen_special.html#preferences 714 | 715 | screen preferences(): 716 | 717 | tag menu 718 | 719 | use game_menu(_("Preferences"), scroll="viewport"): 720 | 721 | vbox: 722 | 723 | hbox: 724 | box_wrap True 725 | 726 | if renpy.variant("pc") or renpy.variant("web"): 727 | 728 | vbox: 729 | style_prefix "radio" 730 | label _("Display") 731 | textbutton _("Window") action Preference("display", "window") 732 | textbutton _("Fullscreen") action Preference("display", "fullscreen") 733 | 734 | vbox: 735 | style_prefix "radio" 736 | label _("Rollback Side") 737 | textbutton _("Disable") action Preference("rollback side", "disable") 738 | textbutton _("Left") action Preference("rollback side", "left") 739 | textbutton _("Right") action Preference("rollback side", "right") 740 | 741 | vbox: 742 | style_prefix "check" 743 | label _("Skip") 744 | textbutton _("Unseen Text") action Preference("skip", "toggle") 745 | textbutton _("After Choices") action Preference("after choices", "toggle") 746 | textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")) 747 | 748 | ## Additional vboxes of type "radio_pref" or "check_pref" can be 749 | ## added here, to add additional creator-defined preferences. 750 | 751 | null height (4 * gui.pref_spacing) 752 | 753 | hbox: 754 | style_prefix "slider" 755 | box_wrap True 756 | 757 | vbox: 758 | 759 | label _("Text Speed") 760 | 761 | bar value Preference("text speed") 762 | 763 | label _("Auto-Forward Time") 764 | 765 | bar value Preference("auto-forward time") 766 | 767 | vbox: 768 | 769 | if config.has_music: 770 | label _("Music Volume") 771 | 772 | hbox: 773 | bar value Preference("music volume") 774 | 775 | if config.has_sound: 776 | 777 | label _("Sound Volume") 778 | 779 | hbox: 780 | bar value Preference("sound volume") 781 | 782 | if config.sample_sound: 783 | textbutton _("Test") action Play("sound", config.sample_sound) 784 | 785 | 786 | if config.has_voice: 787 | label _("Voice Volume") 788 | 789 | hbox: 790 | bar value Preference("voice volume") 791 | 792 | if config.sample_voice: 793 | textbutton _("Test") action Play("voice", config.sample_voice) 794 | 795 | if config.has_music or config.has_sound or config.has_voice: 796 | null height gui.pref_spacing 797 | 798 | textbutton _("Mute All"): 799 | action Preference("all mute", "toggle") 800 | style "mute_all_button" 801 | 802 | 803 | style pref_label is gui_label 804 | style pref_label_text is gui_label_text 805 | style pref_vbox is vbox 806 | 807 | style radio_label is pref_label 808 | style radio_label_text is pref_label_text 809 | style radio_button is gui_button 810 | style radio_button_text is gui_button_text 811 | style radio_vbox is pref_vbox 812 | 813 | style check_label is pref_label 814 | style check_label_text is pref_label_text 815 | style check_button is gui_button 816 | style check_button_text is gui_button_text 817 | style check_vbox is pref_vbox 818 | 819 | style slider_label is pref_label 820 | style slider_label_text is pref_label_text 821 | style slider_slider is gui_slider 822 | style slider_button is gui_button 823 | style slider_button_text is gui_button_text 824 | style slider_pref_vbox is pref_vbox 825 | 826 | style mute_all_button is check_button 827 | style mute_all_button_text is check_button_text 828 | 829 | style pref_label: 830 | top_margin gui.pref_spacing 831 | bottom_margin 2 832 | 833 | style pref_label_text: 834 | yalign 1.0 835 | 836 | style pref_vbox: 837 | xsize 225 838 | 839 | style radio_vbox: 840 | spacing gui.pref_button_spacing 841 | 842 | style radio_button: 843 | properties gui.button_properties("radio_button") 844 | foreground "gui/button/radio_[prefix_]foreground.png" 845 | 846 | style radio_button_text: 847 | properties gui.button_text_properties("radio_button") 848 | 849 | style check_vbox: 850 | spacing gui.pref_button_spacing 851 | 852 | style check_button: 853 | properties gui.button_properties("check_button") 854 | foreground "gui/button/check_[prefix_]foreground.png" 855 | 856 | style check_button_text: 857 | properties gui.button_text_properties("check_button") 858 | 859 | style slider_slider: 860 | xsize 350 861 | 862 | style slider_button: 863 | properties gui.button_properties("slider_button") 864 | yalign 0.5 865 | left_margin 10 866 | 867 | style slider_button_text: 868 | properties gui.button_text_properties("slider_button") 869 | 870 | style slider_vbox: 871 | xsize 450 872 | 873 | 874 | ## History screen ############################################################## 875 | ## 876 | ## This is a screen that displays the dialogue history to the player. While 877 | ## there isn't anything special about this screen, it does have to access the 878 | ## dialogue history stored in _history_list. 879 | ## 880 | ## https://www.renpy.org/doc/html/history.html 881 | 882 | screen history(): 883 | 884 | tag menu 885 | 886 | ## Avoid predicting this screen, as it can be very large. 887 | predict False 888 | 889 | use game_menu(_("History"), scroll=("vpgrid" if gui.history_height else "viewport"), yinitial=1.0): 890 | 891 | style_prefix "history" 892 | 893 | for h in _history_list: 894 | 895 | window: 896 | 897 | ## This lays things out properly if history_height is None. 898 | has fixed: 899 | yfit True 900 | 901 | if h.who: 902 | 903 | label h.who: 904 | style "history_name" 905 | substitute False 906 | 907 | ## Take the color of the who text from the Character, if 908 | ## set. 909 | if "color" in h.who_args: 910 | text_color h.who_args["color"] 911 | 912 | $ what = renpy.filter_text_tags(h.what, allow=gui.history_allow_tags) 913 | text what: 914 | substitute False 915 | 916 | if not _history_list: 917 | label _("The dialogue history is empty.") 918 | 919 | 920 | ## This determines what tags are allowed to be displayed on the history screen. 921 | 922 | define gui.history_allow_tags = { "alt", "noalt" } 923 | 924 | 925 | style history_window is empty 926 | 927 | style history_name is gui_label 928 | style history_name_text is gui_label_text 929 | style history_text is gui_text 930 | 931 | style history_text is gui_text 932 | 933 | style history_label is gui_label 934 | style history_label_text is gui_label_text 935 | 936 | style history_window: 937 | xfill True 938 | ysize gui.history_height 939 | 940 | style history_name: 941 | xpos gui.history_name_xpos 942 | xanchor gui.history_name_xalign 943 | ypos gui.history_name_ypos 944 | xsize gui.history_name_width 945 | 946 | style history_name_text: 947 | min_width gui.history_name_width 948 | text_align gui.history_name_xalign 949 | 950 | style history_text: 951 | xpos gui.history_text_xpos 952 | ypos gui.history_text_ypos 953 | xanchor gui.history_text_xalign 954 | xsize gui.history_text_width 955 | min_width gui.history_text_width 956 | text_align gui.history_text_xalign 957 | layout ("subtitle" if gui.history_text_xalign else "tex") 958 | 959 | style history_label: 960 | xfill True 961 | 962 | style history_label_text: 963 | xalign 0.5 964 | 965 | 966 | ## Help screen ################################################################# 967 | ## 968 | ## A screen that gives information about key and mouse bindings. It uses other 969 | ## screens (keyboard_help, mouse_help, and gamepad_help) to display the actual 970 | ## help. 971 | 972 | screen help(): 973 | 974 | tag menu 975 | 976 | default device = "keyboard" 977 | 978 | use game_menu(_("Help"), scroll="viewport"): 979 | 980 | style_prefix "help" 981 | 982 | vbox: 983 | spacing 15 984 | 985 | hbox: 986 | 987 | textbutton _("Keyboard") action SetScreenVariable("device", "keyboard") 988 | textbutton _("Mouse") action SetScreenVariable("device", "mouse") 989 | 990 | if GamepadExists(): 991 | textbutton _("Gamepad") action SetScreenVariable("device", "gamepad") 992 | 993 | if device == "keyboard": 994 | use keyboard_help 995 | elif device == "mouse": 996 | use mouse_help 997 | elif device == "gamepad": 998 | use gamepad_help 999 | 1000 | 1001 | screen keyboard_help(): 1002 | 1003 | hbox: 1004 | label _("Enter") 1005 | text _("Advances dialogue and activates the interface.") 1006 | 1007 | hbox: 1008 | label _("Space") 1009 | text _("Advances dialogue without selecting choices.") 1010 | 1011 | hbox: 1012 | label _("Arrow Keys") 1013 | text _("Navigate the interface.") 1014 | 1015 | hbox: 1016 | label _("Escape") 1017 | text _("Accesses the game menu.") 1018 | 1019 | hbox: 1020 | label _("Ctrl") 1021 | text _("Skips dialogue while held down.") 1022 | 1023 | hbox: 1024 | label _("Tab") 1025 | text _("Toggles dialogue skipping.") 1026 | 1027 | hbox: 1028 | label _("Page Up") 1029 | text _("Rolls back to earlier dialogue.") 1030 | 1031 | hbox: 1032 | label _("Page Down") 1033 | text _("Rolls forward to later dialogue.") 1034 | 1035 | hbox: 1036 | label "H" 1037 | text _("Hides the user interface.") 1038 | 1039 | hbox: 1040 | label "S" 1041 | text _("Takes a screenshot.") 1042 | 1043 | hbox: 1044 | label "V" 1045 | text _("Toggles assistive {a=https://www.renpy.org/l/voicing}self-voicing{/a}.") 1046 | 1047 | 1048 | screen mouse_help(): 1049 | 1050 | hbox: 1051 | label _("Left Click") 1052 | text _("Advances dialogue and activates the interface.") 1053 | 1054 | hbox: 1055 | label _("Middle Click") 1056 | text _("Hides the user interface.") 1057 | 1058 | hbox: 1059 | label _("Right Click") 1060 | text _("Accesses the game menu.") 1061 | 1062 | hbox: 1063 | label _("Mouse Wheel Up\nClick Rollback Side") 1064 | text _("Rolls back to earlier dialogue.") 1065 | 1066 | hbox: 1067 | label _("Mouse Wheel Down") 1068 | text _("Rolls forward to later dialogue.") 1069 | 1070 | 1071 | screen gamepad_help(): 1072 | 1073 | hbox: 1074 | label _("Right Trigger\nA/Bottom Button") 1075 | text _("Advances dialogue and activates the interface.") 1076 | 1077 | hbox: 1078 | label _("Left Trigger\nLeft Shoulder") 1079 | text _("Rolls back to earlier dialogue.") 1080 | 1081 | hbox: 1082 | label _("Right Shoulder") 1083 | text _("Rolls forward to later dialogue.") 1084 | 1085 | 1086 | hbox: 1087 | label _("D-Pad, Sticks") 1088 | text _("Navigate the interface.") 1089 | 1090 | hbox: 1091 | label _("Start, Guide") 1092 | text _("Accesses the game menu.") 1093 | 1094 | hbox: 1095 | label _("Y/Top Button") 1096 | text _("Hides the user interface.") 1097 | 1098 | textbutton _("Calibrate") action GamepadCalibrate() 1099 | 1100 | 1101 | style help_button is gui_button 1102 | style help_button_text is gui_button_text 1103 | style help_label is gui_label 1104 | style help_label_text is gui_label_text 1105 | style help_text is gui_text 1106 | 1107 | style help_button: 1108 | properties gui.button_properties("help_button") 1109 | xmargin 8 1110 | 1111 | style help_button_text: 1112 | properties gui.button_text_properties("help_button") 1113 | 1114 | style help_label: 1115 | xsize 250 1116 | right_padding 20 1117 | 1118 | style help_label_text: 1119 | size gui.text_size 1120 | xalign 1.0 1121 | text_align 1.0 1122 | 1123 | 1124 | 1125 | ################################################################################ 1126 | ## Additional screens 1127 | ################################################################################ 1128 | 1129 | 1130 | ## Confirm screen ############################################################## 1131 | ## 1132 | ## The confirm screen is called when Ren'Py wants to ask the player a yes or no 1133 | ## question. 1134 | ## 1135 | ## https://www.renpy.org/doc/html/screen_special.html#confirm 1136 | 1137 | screen confirm(message, yes_action, no_action): 1138 | 1139 | ## Ensure other screens do not get input while this screen is displayed. 1140 | modal True 1141 | 1142 | zorder 200 1143 | 1144 | style_prefix "confirm" 1145 | 1146 | add "gui/overlay/confirm.png" 1147 | 1148 | frame: 1149 | 1150 | vbox: 1151 | xalign .5 1152 | yalign .5 1153 | spacing 30 1154 | 1155 | label _(message): 1156 | style "confirm_prompt" 1157 | xalign 0.5 1158 | 1159 | hbox: 1160 | xalign 0.5 1161 | spacing 100 1162 | 1163 | textbutton _("Yes") action yes_action 1164 | textbutton _("No") action no_action 1165 | 1166 | ## Right-click and escape answer "no". 1167 | key "game_menu" action no_action 1168 | 1169 | 1170 | style confirm_frame is gui_frame 1171 | style confirm_prompt is gui_prompt 1172 | style confirm_prompt_text is gui_prompt_text 1173 | style confirm_button is gui_medium_button 1174 | style confirm_button_text is gui_medium_button_text 1175 | 1176 | style confirm_frame: 1177 | background Frame([ "gui/confirm_frame.png", "gui/frame.png"], gui.confirm_frame_borders, tile=gui.frame_tile) 1178 | padding gui.confirm_frame_borders.padding 1179 | xalign .5 1180 | yalign .5 1181 | 1182 | style confirm_prompt_text: 1183 | text_align 0.5 1184 | layout "subtitle" 1185 | 1186 | style confirm_button: 1187 | properties gui.button_properties("confirm_button") 1188 | 1189 | style confirm_button_text: 1190 | properties gui.button_text_properties("confirm_button") 1191 | 1192 | 1193 | ## Skip indicator screen ####################################################### 1194 | ## 1195 | ## The skip_indicator screen is displayed to indicate that skipping is in 1196 | ## progress. 1197 | ## 1198 | ## https://www.renpy.org/doc/html/screen_special.html#skip-indicator 1199 | 1200 | screen skip_indicator(): 1201 | 1202 | zorder 100 1203 | style_prefix "skip" 1204 | 1205 | frame: 1206 | 1207 | hbox: 1208 | spacing 6 1209 | 1210 | text _("Skipping") 1211 | 1212 | text "▸" at delayed_blink(0.0, 1.0) style "skip_triangle" 1213 | text "▸" at delayed_blink(0.2, 1.0) style "skip_triangle" 1214 | text "▸" at delayed_blink(0.4, 1.0) style "skip_triangle" 1215 | 1216 | 1217 | ## This transform is used to blink the arrows one after another. 1218 | transform delayed_blink(delay, cycle): 1219 | alpha .5 1220 | 1221 | pause delay 1222 | 1223 | block: 1224 | linear .2 alpha 1.0 1225 | pause .2 1226 | linear .2 alpha 0.5 1227 | pause (cycle - .4) 1228 | repeat 1229 | 1230 | 1231 | style skip_frame is empty 1232 | style skip_text is gui_text 1233 | style skip_triangle is skip_text 1234 | 1235 | style skip_frame: 1236 | ypos gui.skip_ypos 1237 | background Frame("gui/skip.png", gui.skip_frame_borders, tile=gui.frame_tile) 1238 | padding gui.skip_frame_borders.padding 1239 | 1240 | style skip_text: 1241 | size gui.notify_text_size 1242 | 1243 | style skip_triangle: 1244 | ## We have to use a font that has the BLACK RIGHT-POINTING SMALL TRIANGLE 1245 | ## glyph in it. 1246 | font "DejaVuSans.ttf" 1247 | 1248 | 1249 | ## Notify screen ############################################################### 1250 | ## 1251 | ## The notify screen is used to show the player a message. (For example, when 1252 | ## the game is quicksaved or a screenshot has been taken.) 1253 | ## 1254 | ## https://www.renpy.org/doc/html/screen_special.html#notify-screen 1255 | 1256 | screen notify(message): 1257 | 1258 | zorder 100 1259 | style_prefix "notify" 1260 | 1261 | frame at notify_appear: 1262 | text "[message!tq]" 1263 | 1264 | timer 3.25 action Hide('notify') 1265 | 1266 | 1267 | transform notify_appear: 1268 | on show: 1269 | alpha 0 1270 | linear .25 alpha 1.0 1271 | on hide: 1272 | linear .5 alpha 0.0 1273 | 1274 | 1275 | style notify_frame is empty 1276 | style notify_text is gui_text 1277 | 1278 | style notify_frame: 1279 | ypos gui.notify_ypos 1280 | 1281 | background Frame("gui/notify.png", gui.notify_frame_borders, tile=gui.frame_tile) 1282 | padding gui.notify_frame_borders.padding 1283 | 1284 | style notify_text: 1285 | properties gui.text_properties("notify") 1286 | 1287 | 1288 | ## NVL screen ################################################################## 1289 | ## 1290 | ## This screen is used for NVL-mode dialogue and menus. 1291 | ## 1292 | ## https://www.renpy.org/doc/html/screen_special.html#nvl 1293 | 1294 | 1295 | screen nvl(dialogue, items=None): 1296 | 1297 | window: 1298 | style "nvl_window" 1299 | 1300 | has vbox: 1301 | spacing gui.nvl_spacing 1302 | 1303 | ## Displays dialogue in either a vpgrid or the vbox. 1304 | if gui.nvl_height: 1305 | 1306 | vpgrid: 1307 | cols 1 1308 | yinitial 1.0 1309 | 1310 | use nvl_dialogue(dialogue) 1311 | 1312 | else: 1313 | 1314 | use nvl_dialogue(dialogue) 1315 | 1316 | ## Displays the menu, if given. The menu may be displayed incorrectly if 1317 | ## config.narrator_menu is set to True, as it is above. 1318 | for i in items: 1319 | 1320 | textbutton i.caption: 1321 | action i.action 1322 | style "nvl_button" 1323 | 1324 | add SideImage() xalign 0.0 yalign 1.0 1325 | 1326 | 1327 | screen nvl_dialogue(dialogue): 1328 | 1329 | for d in dialogue: 1330 | 1331 | window: 1332 | id d.window_id 1333 | 1334 | fixed: 1335 | yfit gui.nvl_height is None 1336 | 1337 | if d.who is not None: 1338 | 1339 | text d.who: 1340 | id d.who_id 1341 | 1342 | text d.what: 1343 | id d.what_id 1344 | 1345 | 1346 | ## This controls the maximum number of NVL-mode entries that can be displayed at 1347 | ## once. 1348 | define config.nvl_list_length = gui.nvl_list_length 1349 | 1350 | style nvl_window is default 1351 | style nvl_entry is default 1352 | 1353 | style nvl_label is say_label 1354 | style nvl_dialogue is say_dialogue 1355 | 1356 | style nvl_button is button 1357 | style nvl_button_text is button_text 1358 | 1359 | style nvl_window: 1360 | xfill True 1361 | yfill True 1362 | 1363 | background "gui/nvl.png" 1364 | padding gui.nvl_borders.padding 1365 | 1366 | style nvl_entry: 1367 | xfill True 1368 | ysize gui.nvl_height 1369 | 1370 | style nvl_label: 1371 | xpos gui.nvl_name_xpos 1372 | xanchor gui.nvl_name_xalign 1373 | ypos gui.nvl_name_ypos 1374 | yanchor 0.0 1375 | xsize gui.nvl_name_width 1376 | min_width gui.nvl_name_width 1377 | text_align gui.nvl_name_xalign 1378 | 1379 | style nvl_dialogue: 1380 | xpos gui.nvl_text_xpos 1381 | xanchor gui.nvl_text_xalign 1382 | ypos gui.nvl_text_ypos 1383 | xsize gui.nvl_text_width 1384 | min_width gui.nvl_text_width 1385 | text_align gui.nvl_text_xalign 1386 | layout ("subtitle" if gui.nvl_text_xalign else "tex") 1387 | 1388 | style nvl_thought: 1389 | xpos gui.nvl_thought_xpos 1390 | xanchor gui.nvl_thought_xalign 1391 | ypos gui.nvl_thought_ypos 1392 | xsize gui.nvl_thought_width 1393 | min_width gui.nvl_thought_width 1394 | text_align gui.nvl_thought_xalign 1395 | layout ("subtitle" if gui.nvl_text_xalign else "tex") 1396 | 1397 | style nvl_button: 1398 | properties gui.button_properties("nvl_button") 1399 | xpos gui.nvl_button_xpos 1400 | xanchor gui.nvl_button_xalign 1401 | 1402 | style nvl_button_text: 1403 | properties gui.button_text_properties("nvl_button") 1404 | 1405 | 1406 | 1407 | ################################################################################ 1408 | ## Mobile Variants 1409 | ################################################################################ 1410 | 1411 | style pref_vbox: 1412 | variant "medium" 1413 | xsize 450 1414 | 1415 | ## Since a mouse may not be present, we replace the quick menu with a version 1416 | ## that uses fewer and bigger buttons that are easier to touch. 1417 | screen quick_menu(): 1418 | variant "touch" 1419 | 1420 | zorder 100 1421 | 1422 | if quick_menu: 1423 | 1424 | hbox: 1425 | style_prefix "quick" 1426 | 1427 | xalign 0.5 1428 | yalign 1.0 1429 | 1430 | textbutton _("Back") action Rollback() 1431 | textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True) 1432 | textbutton _("Auto") action Preference("auto-forward", "toggle") 1433 | textbutton _("Menu") action ShowMenu() 1434 | 1435 | 1436 | style window: 1437 | variant "small" 1438 | background "gui/phone/textbox.png" 1439 | 1440 | style radio_button: 1441 | variant "small" 1442 | foreground "gui/phone/button/radio_[prefix_]foreground.png" 1443 | 1444 | style check_button: 1445 | variant "small" 1446 | foreground "gui/phone/button/check_[prefix_]foreground.png" 1447 | 1448 | style nvl_window: 1449 | variant "small" 1450 | background "gui/phone/nvl.png" 1451 | 1452 | style main_menu_frame: 1453 | variant "small" 1454 | background "gui/phone/overlay/main_menu.png" 1455 | 1456 | style game_menu_outer_frame: 1457 | variant "small" 1458 | background "gui/phone/overlay/game_menu.png" 1459 | 1460 | style game_menu_navigation_frame: 1461 | variant "small" 1462 | xsize 340 1463 | 1464 | style game_menu_content_frame: 1465 | variant "small" 1466 | top_margin 0 1467 | 1468 | style pref_vbox: 1469 | variant "small" 1470 | xsize 400 1471 | 1472 | style bar: 1473 | variant "small" 1474 | ysize gui.bar_size 1475 | left_bar Frame("gui/phone/bar/left.png", gui.bar_borders, tile=gui.bar_tile) 1476 | right_bar Frame("gui/phone/bar/right.png", gui.bar_borders, tile=gui.bar_tile) 1477 | 1478 | style vbar: 1479 | variant "small" 1480 | xsize gui.bar_size 1481 | top_bar Frame("gui/phone/bar/top.png", gui.vbar_borders, tile=gui.bar_tile) 1482 | bottom_bar Frame("gui/phone/bar/bottom.png", gui.vbar_borders, tile=gui.bar_tile) 1483 | 1484 | style scrollbar: 1485 | variant "small" 1486 | ysize gui.scrollbar_size 1487 | base_bar Frame("gui/phone/scrollbar/horizontal_[prefix_]bar.png", gui.scrollbar_borders, tile=gui.scrollbar_tile) 1488 | thumb Frame("gui/phone/scrollbar/horizontal_[prefix_]thumb.png", gui.scrollbar_borders, tile=gui.scrollbar_tile) 1489 | 1490 | style vscrollbar: 1491 | variant "small" 1492 | xsize gui.scrollbar_size 1493 | base_bar Frame("gui/phone/scrollbar/vertical_[prefix_]bar.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile) 1494 | thumb Frame("gui/phone/scrollbar/vertical_[prefix_]thumb.png", gui.vscrollbar_borders, tile=gui.scrollbar_tile) 1495 | 1496 | style slider: 1497 | variant "small" 1498 | ysize gui.slider_size 1499 | base_bar Frame("gui/phone/slider/horizontal_[prefix_]bar.png", gui.slider_borders, tile=gui.slider_tile) 1500 | thumb "gui/phone/slider/horizontal_[prefix_]thumb.png" 1501 | 1502 | style vslider: 1503 | variant "small" 1504 | xsize gui.slider_size 1505 | base_bar Frame("gui/phone/slider/vertical_[prefix_]bar.png", gui.vslider_borders, tile=gui.slider_tile) 1506 | thumb "gui/phone/slider/vertical_[prefix_]thumb.png" 1507 | 1508 | style slider_vbox: 1509 | variant "small" 1510 | xsize None 1511 | 1512 | style slider_slider: 1513 | variant "small" 1514 | xsize 600 1515 | -------------------------------------------------------------------------------- /game/script.rpy: -------------------------------------------------------------------------------- 1 | # The script of the game goes in this file. 2 | 3 | # Declare characters used by this game. The color argument colorizes the 4 | # name of the character. 5 | 6 | define e = Character("Eileen") 7 | 8 | 9 | # The game starts here. 10 | 11 | screen tutorial: 12 | frame: 13 | xsize 640 14 | xalign .5 15 | ysize 485 16 | ypos 30 17 | 18 | add Solid('#f8f8ff') 19 | 20 | vbox: 21 | null height 20 22 | textbutton 'Strings' action Jump('strings') left_padding 20 23 | textbutton 'Numbers' action Jump('numbers') left_padding 20 24 | textbutton 'Booleans' action Jump('booleans') left_padding 20 25 | textbutton 'Lists' action Jump('lists') left_padding 20 26 | textbutton 'Sets' action Jump('sets') left_padding 20 27 | textbutton 'Dictionaries' action Jump('dictionaries') left_padding 20 28 | textbutton 'Conditional' action Jump('conditional') left_padding 20 29 | textbutton 'Loop' action Jump('loop') left_padding 20 30 | textbutton 'Iterables' action Jump('iterables') left_padding 20 31 | textbutton 'Functions' action Jump('functions') left_padding 20 32 | textbutton 'Classes' action Jump('classes') left_padding 20 33 | 34 | label start: 35 | 36 | scene bg room 37 | show eileen happy 38 | hide screen example # code snippet example 39 | show screen tutorial 40 | 41 | # These display lines of dialogue. 42 | 43 | # Lines that start with $ is intepreted as a Python statement 44 | $ print('Hello World!') 45 | 46 | python: 47 | # Lines that start with # is a comment and won't be evaluated by Ren'Py or Python 48 | print("Let's learn Python to power up our Ren'Py games") 49 | print("Are you ready?") 50 | 51 | # anything stored in persistent persists across game relaunches 52 | $ persistent.player_name = 'Python newbie' 53 | 54 | e "Welcome [persistent.player_name]. You've created a new Ren'Py game." 55 | 56 | e "Once you add a story, pictures, and music, you can release it to the world!" 57 | 58 | # This ends the game. 59 | 60 | return 61 | -------------------------------------------------------------------------------- /game/sets.rpy: -------------------------------------------------------------------------------- 1 | #begin sets 2 | label sets: 3 | hide screen tutorial 4 | show screen example('sets') 5 | 6 | python: 7 | fruit_list = ['apple', 'banana', 'pear', 'apple'] 8 | fruit_set = set(fruit_list) 9 | 10 | num_fruits = len(fruit_list) 11 | num_fruit_types = len(fruit_set) 12 | 13 | e "We have [num_fruits] fruits and [num_fruit_types] types of fruits." 14 | 15 | label sets_choices: 16 | menu: 17 | "Let's get some different types of fruits. What shall we get?" 18 | 19 | "Mangoes": 20 | if 'mango' in fruit_set: 21 | e "We already have mangoes." 22 | else: 23 | $ fruit_set.add('mango') 24 | e "We got mangoes!" 25 | jump sets_choices 26 | 27 | "Apples": 28 | if 'apple' in fruit_set: 29 | e "We already have apples." 30 | jump sets_choices 31 | 32 | "We have everything we need!": 33 | pass 34 | 35 | $ num_fruit_types = len(fruit_set) 36 | e "We now have [num_fruit_types] types of fruits." 37 | 38 | jump start 39 | #end sets -------------------------------------------------------------------------------- /game/strings.rpy: -------------------------------------------------------------------------------- 1 | label strings: 2 | hide screen tutorial 3 | show screen example('strings') 4 | 5 | # show code example as in the Ren'Py official tutorial 6 | #begin strings 7 | $ string = "Learning Python for Ren'Py is fun!" 8 | e "I said: [string]" 9 | 10 | $ len_string = len(string) 11 | e "The string has a length of [len_string]" 12 | 13 | $ last_character = string[-1] 14 | e "The last character of the string is: [last_character]" 15 | 16 | $ string_uppercase = string.upper() 17 | e "I said: [string_uppercase]!!!!!" 18 | #end strings 19 | 20 | jump start -------------------------------------------------------------------------------- /game/tl/None/common.rpym: -------------------------------------------------------------------------------- 1 |  2 | translate None strings: 3 | 4 | # renpy/common/00accessibility.rpy:28 5 | old "Self-voicing disabled." 6 | new "Self-voicing disabled." 7 | 8 | # renpy/common/00accessibility.rpy:29 9 | old "Clipboard voicing enabled. " 10 | new "Clipboard voicing enabled. " 11 | 12 | # renpy/common/00accessibility.rpy:30 13 | old "Self-voicing enabled. " 14 | new "Self-voicing enabled. " 15 | 16 | # renpy/common/00accessibility.rpy:32 17 | old "bar" 18 | new "bar" 19 | 20 | # renpy/common/00accessibility.rpy:33 21 | old "selected" 22 | new "selected" 23 | 24 | # renpy/common/00accessibility.rpy:34 25 | old "viewport" 26 | new "viewport" 27 | 28 | # renpy/common/00accessibility.rpy:35 29 | old "horizontal scroll" 30 | new "horizontal scroll" 31 | 32 | # renpy/common/00accessibility.rpy:36 33 | old "vertical scroll" 34 | new "vertical scroll" 35 | 36 | # renpy/common/00accessibility.rpy:37 37 | old "activate" 38 | new "activate" 39 | 40 | # renpy/common/00accessibility.rpy:38 41 | old "deactivate" 42 | new "deactivate" 43 | 44 | # renpy/common/00accessibility.rpy:39 45 | old "increase" 46 | new "increase" 47 | 48 | # renpy/common/00accessibility.rpy:40 49 | old "decrease" 50 | new "decrease" 51 | 52 | # renpy/common/00accessibility.rpy:128 53 | old "Font Override" 54 | new "Font Override" 55 | 56 | # renpy/common/00accessibility.rpy:132 57 | old "Default" 58 | new "Default" 59 | 60 | # renpy/common/00accessibility.rpy:136 61 | old "DejaVu Sans" 62 | new "DejaVu Sans" 63 | 64 | # renpy/common/00accessibility.rpy:140 65 | old "Opendyslexic" 66 | new "Opendyslexic" 67 | 68 | # renpy/common/00accessibility.rpy:146 69 | old "Text Size Scaling" 70 | new "Text Size Scaling" 71 | 72 | # renpy/common/00accessibility.rpy:152 73 | old "Reset" 74 | new "Reset" 75 | 76 | # renpy/common/00accessibility.rpy:158 77 | old "Line Spacing Scaling" 78 | new "Line Spacing Scaling" 79 | 80 | # renpy/common/00accessibility.rpy:171 81 | old "Self-Voicing" 82 | new "Self-Voicing" 83 | 84 | # renpy/common/00accessibility.rpy:175 85 | old "Off" 86 | new "Off" 87 | 88 | # renpy/common/00accessibility.rpy:179 89 | old "Text-to-speech" 90 | new "Text-to-speech" 91 | 92 | # renpy/common/00accessibility.rpy:183 93 | old "Clipboard" 94 | new "Clipboard" 95 | 96 | # renpy/common/00accessibility.rpy:187 97 | old "Debug" 98 | new "Debug" 99 | 100 | # renpy/common/00accessibility.rpy:193 101 | old "Self-Voicing Volume Drop" 102 | new "Self-Voicing Volume Drop" 103 | 104 | # renpy/common/00accessibility.rpy:202 105 | old "The options on this menu are intended to improve accessibility. They may not work with all games, and some combinations of options may render the game unplayable. This is not an issue with the game or engine. For the best results when changing fonts, try to keep the text size the same as it originally was." 106 | new "The options on this menu are intended to improve accessibility. They may not work with all games, and some combinations of options may render the game unplayable. This is not an issue with the game or engine. For the best results when changing fonts, try to keep the text size the same as it originally was." 107 | 108 | # renpy/common/00accessibility.rpy:207 109 | old "Return" 110 | new "Return" 111 | 112 | # renpy/common/00action_file.rpy:26 113 | old "{#weekday}Monday" 114 | new "{#weekday}Monday" 115 | 116 | # renpy/common/00action_file.rpy:26 117 | old "{#weekday}Tuesday" 118 | new "{#weekday}Tuesday" 119 | 120 | # renpy/common/00action_file.rpy:26 121 | old "{#weekday}Wednesday" 122 | new "{#weekday}Wednesday" 123 | 124 | # renpy/common/00action_file.rpy:26 125 | old "{#weekday}Thursday" 126 | new "{#weekday}Thursday" 127 | 128 | # renpy/common/00action_file.rpy:26 129 | old "{#weekday}Friday" 130 | new "{#weekday}Friday" 131 | 132 | # renpy/common/00action_file.rpy:26 133 | old "{#weekday}Saturday" 134 | new "{#weekday}Saturday" 135 | 136 | # renpy/common/00action_file.rpy:26 137 | old "{#weekday}Sunday" 138 | new "{#weekday}Sunday" 139 | 140 | # renpy/common/00action_file.rpy:37 141 | old "{#weekday_short}Mon" 142 | new "{#weekday_short}Mon" 143 | 144 | # renpy/common/00action_file.rpy:37 145 | old "{#weekday_short}Tue" 146 | new "{#weekday_short}Tue" 147 | 148 | # renpy/common/00action_file.rpy:37 149 | old "{#weekday_short}Wed" 150 | new "{#weekday_short}Wed" 151 | 152 | # renpy/common/00action_file.rpy:37 153 | old "{#weekday_short}Thu" 154 | new "{#weekday_short}Thu" 155 | 156 | # renpy/common/00action_file.rpy:37 157 | old "{#weekday_short}Fri" 158 | new "{#weekday_short}Fri" 159 | 160 | # renpy/common/00action_file.rpy:37 161 | old "{#weekday_short}Sat" 162 | new "{#weekday_short}Sat" 163 | 164 | # renpy/common/00action_file.rpy:37 165 | old "{#weekday_short}Sun" 166 | new "{#weekday_short}Sun" 167 | 168 | # renpy/common/00action_file.rpy:47 169 | old "{#month}January" 170 | new "{#month}January" 171 | 172 | # renpy/common/00action_file.rpy:47 173 | old "{#month}February" 174 | new "{#month}February" 175 | 176 | # renpy/common/00action_file.rpy:47 177 | old "{#month}March" 178 | new "{#month}March" 179 | 180 | # renpy/common/00action_file.rpy:47 181 | old "{#month}April" 182 | new "{#month}April" 183 | 184 | # renpy/common/00action_file.rpy:47 185 | old "{#month}May" 186 | new "{#month}May" 187 | 188 | # renpy/common/00action_file.rpy:47 189 | old "{#month}June" 190 | new "{#month}June" 191 | 192 | # renpy/common/00action_file.rpy:47 193 | old "{#month}July" 194 | new "{#month}July" 195 | 196 | # renpy/common/00action_file.rpy:47 197 | old "{#month}August" 198 | new "{#month}August" 199 | 200 | # renpy/common/00action_file.rpy:47 201 | old "{#month}September" 202 | new "{#month}September" 203 | 204 | # renpy/common/00action_file.rpy:47 205 | old "{#month}October" 206 | new "{#month}October" 207 | 208 | # renpy/common/00action_file.rpy:47 209 | old "{#month}November" 210 | new "{#month}November" 211 | 212 | # renpy/common/00action_file.rpy:47 213 | old "{#month}December" 214 | new "{#month}December" 215 | 216 | # renpy/common/00action_file.rpy:63 217 | old "{#month_short}Jan" 218 | new "{#month_short}Jan" 219 | 220 | # renpy/common/00action_file.rpy:63 221 | old "{#month_short}Feb" 222 | new "{#month_short}Feb" 223 | 224 | # renpy/common/00action_file.rpy:63 225 | old "{#month_short}Mar" 226 | new "{#month_short}Mar" 227 | 228 | # renpy/common/00action_file.rpy:63 229 | old "{#month_short}Apr" 230 | new "{#month_short}Apr" 231 | 232 | # renpy/common/00action_file.rpy:63 233 | old "{#month_short}May" 234 | new "{#month_short}May" 235 | 236 | # renpy/common/00action_file.rpy:63 237 | old "{#month_short}Jun" 238 | new "{#month_short}Jun" 239 | 240 | # renpy/common/00action_file.rpy:63 241 | old "{#month_short}Jul" 242 | new "{#month_short}Jul" 243 | 244 | # renpy/common/00action_file.rpy:63 245 | old "{#month_short}Aug" 246 | new "{#month_short}Aug" 247 | 248 | # renpy/common/00action_file.rpy:63 249 | old "{#month_short}Sep" 250 | new "{#month_short}Sep" 251 | 252 | # renpy/common/00action_file.rpy:63 253 | old "{#month_short}Oct" 254 | new "{#month_short}Oct" 255 | 256 | # renpy/common/00action_file.rpy:63 257 | old "{#month_short}Nov" 258 | new "{#month_short}Nov" 259 | 260 | # renpy/common/00action_file.rpy:63 261 | old "{#month_short}Dec" 262 | new "{#month_short}Dec" 263 | 264 | # renpy/common/00action_file.rpy:240 265 | old "%b %d, %H:%M" 266 | new "%b %d, %H:%M" 267 | 268 | # renpy/common/00action_file.rpy:353 269 | old "Save slot %s: [text]" 270 | new "Save slot %s: [text]" 271 | 272 | # renpy/common/00action_file.rpy:434 273 | old "Load slot %s: [text]" 274 | new "Load slot %s: [text]" 275 | 276 | # renpy/common/00action_file.rpy:487 277 | old "Delete slot [text]" 278 | new "Delete slot [text]" 279 | 280 | # renpy/common/00action_file.rpy:566 281 | old "File page auto" 282 | new "File page auto" 283 | 284 | # renpy/common/00action_file.rpy:568 285 | old "File page quick" 286 | new "File page quick" 287 | 288 | # renpy/common/00action_file.rpy:570 289 | old "File page [text]" 290 | new "File page [text]" 291 | 292 | # renpy/common/00action_file.rpy:628 293 | old "Page {}" 294 | new "Page {}" 295 | 296 | # renpy/common/00action_file.rpy:628 297 | old "Automatic saves" 298 | new "Automatic saves" 299 | 300 | # renpy/common/00action_file.rpy:628 301 | old "Quick saves" 302 | new "Quick saves" 303 | 304 | # renpy/common/00action_file.rpy:769 305 | old "Next file page." 306 | new "Next file page." 307 | 308 | # renpy/common/00action_file.rpy:841 309 | old "Previous file page." 310 | new "Previous file page." 311 | 312 | # renpy/common/00action_file.rpy:902 313 | old "Quick save complete." 314 | new "Quick save complete." 315 | 316 | # renpy/common/00action_file.rpy:920 317 | old "Quick save." 318 | new "Quick save." 319 | 320 | # renpy/common/00action_file.rpy:939 321 | old "Quick load." 322 | new "Quick load." 323 | 324 | # renpy/common/00action_other.rpy:375 325 | old "Language [text]" 326 | new "Language [text]" 327 | 328 | # renpy/common/00director.rpy:708 329 | old "The interactive director is not enabled here." 330 | new "The interactive director is not enabled here." 331 | 332 | # renpy/common/00director.rpy:1481 333 | old "⬆" 334 | new "⬆" 335 | 336 | # renpy/common/00director.rpy:1487 337 | old "⬇" 338 | new "⬇" 339 | 340 | # renpy/common/00director.rpy:1551 341 | old "Done" 342 | new "Done" 343 | 344 | # renpy/common/00director.rpy:1561 345 | old "(statement)" 346 | new "(statement)" 347 | 348 | # renpy/common/00director.rpy:1562 349 | old "(tag)" 350 | new "(tag)" 351 | 352 | # renpy/common/00director.rpy:1563 353 | old "(attributes)" 354 | new "(attributes)" 355 | 356 | # renpy/common/00director.rpy:1564 357 | old "(transform)" 358 | new "(transform)" 359 | 360 | # renpy/common/00director.rpy:1589 361 | old "(transition)" 362 | new "(transition)" 363 | 364 | # renpy/common/00director.rpy:1601 365 | old "(channel)" 366 | new "(channel)" 367 | 368 | # renpy/common/00director.rpy:1602 369 | old "(filename)" 370 | new "(filename)" 371 | 372 | # renpy/common/00director.rpy:1631 373 | old "Change" 374 | new "Change" 375 | 376 | # renpy/common/00director.rpy:1633 377 | old "Add" 378 | new "Add" 379 | 380 | # renpy/common/00director.rpy:1636 381 | old "Cancel" 382 | new "Cancel" 383 | 384 | # renpy/common/00director.rpy:1639 385 | old "Remove" 386 | new "Remove" 387 | 388 | # renpy/common/00director.rpy:1674 389 | old "Statement:" 390 | new "Statement:" 391 | 392 | # renpy/common/00director.rpy:1695 393 | old "Tag:" 394 | new "Tag:" 395 | 396 | # renpy/common/00director.rpy:1711 397 | old "Attributes:" 398 | new "Attributes:" 399 | 400 | # renpy/common/00director.rpy:1729 401 | old "Transforms:" 402 | new "Transforms:" 403 | 404 | # renpy/common/00director.rpy:1748 405 | old "Behind:" 406 | new "Behind:" 407 | 408 | # renpy/common/00director.rpy:1767 409 | old "Transition:" 410 | new "Transition:" 411 | 412 | # renpy/common/00director.rpy:1785 413 | old "Channel:" 414 | new "Channel:" 415 | 416 | # renpy/common/00director.rpy:1803 417 | old "Audio Filename:" 418 | new "Audio Filename:" 419 | 420 | # renpy/common/00gui.rpy:374 421 | old "Are you sure?" 422 | new "Are you sure?" 423 | 424 | # renpy/common/00gui.rpy:375 425 | old "Are you sure you want to delete this save?" 426 | new "Are you sure you want to delete this save?" 427 | 428 | # renpy/common/00gui.rpy:376 429 | old "Are you sure you want to overwrite your save?" 430 | new "Are you sure you want to overwrite your save?" 431 | 432 | # renpy/common/00gui.rpy:377 433 | old "Loading will lose unsaved progress.\nAre you sure you want to do this?" 434 | new "Loading will lose unsaved progress.\nAre you sure you want to do this?" 435 | 436 | # renpy/common/00gui.rpy:378 437 | old "Are you sure you want to quit?" 438 | new "Are you sure you want to quit?" 439 | 440 | # renpy/common/00gui.rpy:379 441 | old "Are you sure you want to return to the main menu?\nThis will lose unsaved progress." 442 | new "Are you sure you want to return to the main menu?\nThis will lose unsaved progress." 443 | 444 | # renpy/common/00gui.rpy:380 445 | old "Are you sure you want to end the replay?" 446 | new "Are you sure you want to end the replay?" 447 | 448 | # renpy/common/00gui.rpy:381 449 | old "Are you sure you want to begin skipping?" 450 | new "Are you sure you want to begin skipping?" 451 | 452 | # renpy/common/00gui.rpy:382 453 | old "Are you sure you want to skip to the next choice?" 454 | new "Are you sure you want to skip to the next choice?" 455 | 456 | # renpy/common/00gui.rpy:383 457 | old "Are you sure you want to skip unseen dialogue to the next choice?" 458 | new "Are you sure you want to skip unseen dialogue to the next choice?" 459 | 460 | # renpy/common/00keymap.rpy:300 461 | old "Failed to save screenshot as %s." 462 | new "Failed to save screenshot as %s." 463 | 464 | # renpy/common/00keymap.rpy:312 465 | old "Saved screenshot as %s." 466 | new "Saved screenshot as %s." 467 | 468 | # renpy/common/00library.rpy:195 469 | old "Skip Mode" 470 | new "Skip Mode" 471 | 472 | # renpy/common/00library.rpy:281 473 | old "This program contains free software under a number of licenses, including the MIT License and GNU Lesser General Public License. A complete list of software, including links to full source code, can be found {a=https://www.renpy.org/l/license}here{/a}." 474 | new "This program contains free software under a number of licenses, including the MIT License and GNU Lesser General Public License. A complete list of software, including links to full source code, can be found {a=https://www.renpy.org/l/license}here{/a}." 475 | 476 | # renpy/common/00preferences.rpy:240 477 | old "display" 478 | new "display" 479 | 480 | # renpy/common/00preferences.rpy:252 481 | old "transitions" 482 | new "transitions" 483 | 484 | # renpy/common/00preferences.rpy:261 485 | old "skip transitions" 486 | new "skip transitions" 487 | 488 | # renpy/common/00preferences.rpy:263 489 | old "video sprites" 490 | new "video sprites" 491 | 492 | # renpy/common/00preferences.rpy:272 493 | old "show empty window" 494 | new "show empty window" 495 | 496 | # renpy/common/00preferences.rpy:281 497 | old "text speed" 498 | new "text speed" 499 | 500 | # renpy/common/00preferences.rpy:289 501 | old "joystick" 502 | new "joystick" 503 | 504 | # renpy/common/00preferences.rpy:289 505 | old "joystick..." 506 | new "joystick..." 507 | 508 | # renpy/common/00preferences.rpy:296 509 | old "skip" 510 | new "skip" 511 | 512 | # renpy/common/00preferences.rpy:299 513 | old "skip unseen [text]" 514 | new "skip unseen [text]" 515 | 516 | # renpy/common/00preferences.rpy:304 517 | old "skip unseen text" 518 | new "skip unseen text" 519 | 520 | # renpy/common/00preferences.rpy:306 521 | old "begin skipping" 522 | new "begin skipping" 523 | 524 | # renpy/common/00preferences.rpy:310 525 | old "after choices" 526 | new "after choices" 527 | 528 | # renpy/common/00preferences.rpy:317 529 | old "skip after choices" 530 | new "skip after choices" 531 | 532 | # renpy/common/00preferences.rpy:319 533 | old "auto-forward time" 534 | new "auto-forward time" 535 | 536 | # renpy/common/00preferences.rpy:333 537 | old "auto-forward" 538 | new "auto-forward" 539 | 540 | # renpy/common/00preferences.rpy:340 541 | old "Auto forward" 542 | new "Auto forward" 543 | 544 | # renpy/common/00preferences.rpy:343 545 | old "auto-forward after click" 546 | new "auto-forward after click" 547 | 548 | # renpy/common/00preferences.rpy:352 549 | old "automatic move" 550 | new "automatic move" 551 | 552 | # renpy/common/00preferences.rpy:361 553 | old "wait for voice" 554 | new "wait for voice" 555 | 556 | # renpy/common/00preferences.rpy:370 557 | old "voice sustain" 558 | new "voice sustain" 559 | 560 | # renpy/common/00preferences.rpy:379 561 | old "self voicing" 562 | new "self voicing" 563 | 564 | # renpy/common/00preferences.rpy:388 565 | old "self voicing volume drop" 566 | new "self voicing volume drop" 567 | 568 | # renpy/common/00preferences.rpy:396 569 | old "clipboard voicing" 570 | new "clipboard voicing" 571 | 572 | # renpy/common/00preferences.rpy:405 573 | old "debug voicing" 574 | new "debug voicing" 575 | 576 | # renpy/common/00preferences.rpy:414 577 | old "emphasize audio" 578 | new "emphasize audio" 579 | 580 | # renpy/common/00preferences.rpy:423 581 | old "rollback side" 582 | new "rollback side" 583 | 584 | # renpy/common/00preferences.rpy:433 585 | old "gl powersave" 586 | new "gl powersave" 587 | 588 | # renpy/common/00preferences.rpy:439 589 | old "gl framerate" 590 | new "gl framerate" 591 | 592 | # renpy/common/00preferences.rpy:442 593 | old "gl tearing" 594 | new "gl tearing" 595 | 596 | # renpy/common/00preferences.rpy:445 597 | old "font transform" 598 | new "font transform" 599 | 600 | # renpy/common/00preferences.rpy:448 601 | old "font size" 602 | new "font size" 603 | 604 | # renpy/common/00preferences.rpy:456 605 | old "font line spacing" 606 | new "font line spacing" 607 | 608 | # renpy/common/00preferences.rpy:464 609 | old "system cursor" 610 | new "system cursor" 611 | 612 | # renpy/common/00preferences.rpy:484 613 | old "music volume" 614 | new "music volume" 615 | 616 | # renpy/common/00preferences.rpy:485 617 | old "sound volume" 618 | new "sound volume" 619 | 620 | # renpy/common/00preferences.rpy:486 621 | old "voice volume" 622 | new "voice volume" 623 | 624 | # renpy/common/00preferences.rpy:487 625 | old "mute music" 626 | new "mute music" 627 | 628 | # renpy/common/00preferences.rpy:488 629 | old "mute sound" 630 | new "mute sound" 631 | 632 | # renpy/common/00preferences.rpy:489 633 | old "mute voice" 634 | new "mute voice" 635 | 636 | # renpy/common/00preferences.rpy:490 637 | old "mute all" 638 | new "mute all" 639 | 640 | # renpy/common/00preferences.rpy:571 641 | old "Clipboard voicing enabled. Press 'shift+C' to disable." 642 | new "Clipboard voicing enabled. Press 'shift+C' to disable." 643 | 644 | # renpy/common/00preferences.rpy:573 645 | old "Self-voicing would say \"[renpy.display.tts.last]\". Press 'alt+shift+V' to disable." 646 | new "Self-voicing would say \"[renpy.display.tts.last]\". Press 'alt+shift+V' to disable." 647 | 648 | # renpy/common/00preferences.rpy:575 649 | old "Self-voicing enabled. Press 'v' to disable." 650 | new "Self-voicing enabled. Press 'v' to disable." 651 | 652 | # renpy/common/00iap.rpy:219 653 | old "Contacting App Store\nPlease Wait..." 654 | new "Contacting App Store\nPlease Wait..." 655 | 656 | # renpy/common/00updater.rpy:374 657 | old "The Ren'Py Updater is not supported on mobile devices." 658 | new "The Ren'Py Updater is not supported on mobile devices." 659 | 660 | # renpy/common/00updater.rpy:493 661 | old "An error is being simulated." 662 | new "An error is being simulated." 663 | 664 | # renpy/common/00updater.rpy:677 665 | old "Either this project does not support updating, or the update status file was deleted." 666 | new "Either this project does not support updating, or the update status file was deleted." 667 | 668 | # renpy/common/00updater.rpy:691 669 | old "This account does not have permission to perform an update." 670 | new "This account does not have permission to perform an update." 671 | 672 | # renpy/common/00updater.rpy:694 673 | old "This account does not have permission to write the update log." 674 | new "This account does not have permission to write the update log." 675 | 676 | # renpy/common/00updater.rpy:721 677 | old "Could not verify update signature." 678 | new "Could not verify update signature." 679 | 680 | # renpy/common/00updater.rpy:992 681 | old "The update file was not downloaded." 682 | new "The update file was not downloaded." 683 | 684 | # renpy/common/00updater.rpy:1010 685 | old "The update file does not have the correct digest - it may have been corrupted." 686 | new "The update file does not have the correct digest - it may have been corrupted." 687 | 688 | # renpy/common/00updater.rpy:1064 689 | old "While unpacking {}, unknown type {}." 690 | new "While unpacking {}, unknown type {}." 691 | 692 | # renpy/common/00updater.rpy:1430 693 | old "Updater" 694 | new "Updater" 695 | 696 | # renpy/common/00updater.rpy:1437 697 | old "An error has occured:" 698 | new "An error has occured:" 699 | 700 | # renpy/common/00updater.rpy:1439 701 | old "Checking for updates." 702 | new "Checking for updates." 703 | 704 | # renpy/common/00updater.rpy:1441 705 | old "This program is up to date." 706 | new "This program is up to date." 707 | 708 | # renpy/common/00updater.rpy:1443 709 | old "[u.version] is available. Do you want to install it?" 710 | new "[u.version] is available. Do you want to install it?" 711 | 712 | # renpy/common/00updater.rpy:1445 713 | old "Preparing to download the updates." 714 | new "Preparing to download the updates." 715 | 716 | # renpy/common/00updater.rpy:1447 717 | old "Downloading the updates." 718 | new "Downloading the updates." 719 | 720 | # renpy/common/00updater.rpy:1449 721 | old "Unpacking the updates." 722 | new "Unpacking the updates." 723 | 724 | # renpy/common/00updater.rpy:1451 725 | old "Finishing up." 726 | new "Finishing up." 727 | 728 | # renpy/common/00updater.rpy:1453 729 | old "The updates have been installed. The program will restart." 730 | new "The updates have been installed. The program will restart." 731 | 732 | # renpy/common/00updater.rpy:1455 733 | old "The updates have been installed." 734 | new "The updates have been installed." 735 | 736 | # renpy/common/00updater.rpy:1457 737 | old "The updates were cancelled." 738 | new "The updates were cancelled." 739 | 740 | # renpy/common/00updater.rpy:1472 741 | old "Proceed" 742 | new "Proceed" 743 | 744 | # renpy/common/00compat.rpy:305 745 | old "Fullscreen" 746 | new "Fullscreen" 747 | 748 | # renpy/common/00gallery.rpy:590 749 | old "Image [index] of [count] locked." 750 | new "Image [index] of [count] locked." 751 | 752 | # renpy/common/00gallery.rpy:610 753 | old "prev" 754 | new "prev" 755 | 756 | # renpy/common/00gallery.rpy:611 757 | old "next" 758 | new "next" 759 | 760 | # renpy/common/00gallery.rpy:612 761 | old "slideshow" 762 | new "slideshow" 763 | 764 | # renpy/common/00gallery.rpy:613 765 | old "return" 766 | new "return" 767 | 768 | # renpy/common/00gltest.rpy:89 769 | old "Renderer" 770 | new "Renderer" 771 | 772 | # renpy/common/00gltest.rpy:93 773 | old "Automatically Choose" 774 | new "Automatically Choose" 775 | 776 | # renpy/common/00gltest.rpy:100 777 | old "Force GL Renderer" 778 | new "Force GL Renderer" 779 | 780 | # renpy/common/00gltest.rpy:105 781 | old "Force ANGLE Renderer" 782 | new "Force ANGLE Renderer" 783 | 784 | # renpy/common/00gltest.rpy:110 785 | old "Force GLES Renderer" 786 | new "Force GLES Renderer" 787 | 788 | # renpy/common/00gltest.rpy:116 789 | old "Force GL2 Renderer" 790 | new "Force GL2 Renderer" 791 | 792 | # renpy/common/00gltest.rpy:121 793 | old "Force ANGLE2 Renderer" 794 | new "Force ANGLE2 Renderer" 795 | 796 | # renpy/common/00gltest.rpy:126 797 | old "Force GLES2 Renderer" 798 | new "Force GLES2 Renderer" 799 | 800 | # renpy/common/00gltest.rpy:132 801 | old "Gamepad" 802 | new "Gamepad" 803 | 804 | # renpy/common/00gltest.rpy:136 805 | old "Enable (No Blocklist)" 806 | new "Enable (No Blocklist)" 807 | 808 | # renpy/common/00gltest.rpy:140 809 | old "Enable" 810 | new "Enable" 811 | 812 | # renpy/common/00gltest.rpy:144 813 | old "Disable" 814 | new "Disable" 815 | 816 | # renpy/common/00gltest.rpy:150 817 | old "Calibrate" 818 | new "Calibrate" 819 | 820 | # renpy/common/00gltest.rpy:159 821 | old "Powersave" 822 | new "Powersave" 823 | 824 | # renpy/common/00gltest.rpy:173 825 | old "Framerate" 826 | new "Framerate" 827 | 828 | # renpy/common/00gltest.rpy:177 829 | old "Screen" 830 | new "Screen" 831 | 832 | # renpy/common/00gltest.rpy:181 833 | old "60" 834 | new "60" 835 | 836 | # renpy/common/00gltest.rpy:185 837 | old "30" 838 | new "30" 839 | 840 | # renpy/common/00gltest.rpy:191 841 | old "Tearing" 842 | new "Tearing" 843 | 844 | # renpy/common/00gltest.rpy:207 845 | old "Changes will take effect the next time this program is run." 846 | new "Changes will take effect the next time this program is run." 847 | 848 | # renpy/common/00gltest.rpy:214 849 | old "Quit" 850 | new "Quit" 851 | 852 | # renpy/common/00gltest.rpy:242 853 | old "Performance Warning" 854 | new "Performance Warning" 855 | 856 | # renpy/common/00gltest.rpy:247 857 | old "This computer is using software rendering." 858 | new "This computer is using software rendering." 859 | 860 | # renpy/common/00gltest.rpy:249 861 | old "This game requires use of GL2 that can't be initialised." 862 | new "This game requires use of GL2 that can't be initialised." 863 | 864 | # renpy/common/00gltest.rpy:251 865 | old "This computer has a problem displaying graphics: [problem]." 866 | new "This computer has a problem displaying graphics: [problem]." 867 | 868 | # renpy/common/00gltest.rpy:255 869 | old "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display." 870 | new "Its graphics drivers may be out of date or not operating correctly. This can lead to slow or incorrect graphics display." 871 | 872 | # renpy/common/00gltest.rpy:259 873 | old "The {a=edit:1:log.txt}log.txt{/a} file may contain information to help you determine what is wrong with your computer." 874 | new "The {a=edit:1:log.txt}log.txt{/a} file may contain information to help you determine what is wrong with your computer." 875 | 876 | # renpy/common/00gltest.rpy:264 877 | old "More details on how to fix this can be found in the {a=[url]}documentation{/a}." 878 | new "More details on how to fix this can be found in the {a=[url]}documentation{/a}." 879 | 880 | # renpy/common/00gltest.rpy:269 881 | old "Continue, Show this warning again" 882 | new "Continue, Show this warning again" 883 | 884 | # renpy/common/00gltest.rpy:273 885 | old "Continue, Don't show warning again" 886 | new "Continue, Don't show warning again" 887 | 888 | # renpy/common/00gltest.rpy:281 889 | old "Change render options" 890 | new "Change render options" 891 | 892 | # renpy/common/00gamepad.rpy:32 893 | old "Select Gamepad to Calibrate" 894 | new "Select Gamepad to Calibrate" 895 | 896 | # renpy/common/00gamepad.rpy:35 897 | old "No Gamepads Available" 898 | new "No Gamepads Available" 899 | 900 | # renpy/common/00gamepad.rpy:54 901 | old "Calibrating [name] ([i]/[total])" 902 | new "Calibrating [name] ([i]/[total])" 903 | 904 | # renpy/common/00gamepad.rpy:58 905 | old "Press or move the '[control!s]' [kind]." 906 | new "Press or move the '[control!s]' [kind]." 907 | 908 | # renpy/common/00gamepad.rpy:68 909 | old "Skip (A)" 910 | new "Skip (A)" 911 | 912 | # renpy/common/00gamepad.rpy:71 913 | old "Back (B)" 914 | new "Back (B)" 915 | 916 | # renpy/common/_errorhandling.rpym:542 917 | old "Open" 918 | new "Open" 919 | 920 | # renpy/common/_errorhandling.rpym:544 921 | old "Opens the traceback.txt file in a text editor." 922 | new "Opens the traceback.txt file in a text editor." 923 | 924 | # renpy/common/_errorhandling.rpym:546 925 | old "Copy BBCode" 926 | new "Copy BBCode" 927 | 928 | # renpy/common/_errorhandling.rpym:548 929 | old "Copies the traceback.txt file to the clipboard as BBcode for forums like https://lemmasoft.renai.us/." 930 | new "Copies the traceback.txt file to the clipboard as BBcode for forums like https://lemmasoft.renai.us/." 931 | 932 | # renpy/common/_errorhandling.rpym:550 933 | old "Copy Markdown" 934 | new "Copy Markdown" 935 | 936 | # renpy/common/_errorhandling.rpym:552 937 | old "Copies the traceback.txt file to the clipboard as Markdown for Discord." 938 | new "Copies the traceback.txt file to the clipboard as Markdown for Discord." 939 | 940 | # renpy/common/_errorhandling.rpym:581 941 | old "An exception has occurred." 942 | new "An exception has occurred." 943 | 944 | # renpy/common/_errorhandling.rpym:604 945 | old "Rollback" 946 | new "Rollback" 947 | 948 | # renpy/common/_errorhandling.rpym:606 949 | old "Attempts a roll back to a prior time, allowing you to save or choose a different choice." 950 | new "Attempts a roll back to a prior time, allowing you to save or choose a different choice." 951 | 952 | # renpy/common/_errorhandling.rpym:609 953 | old "Ignore" 954 | new "Ignore" 955 | 956 | # renpy/common/_errorhandling.rpym:613 957 | old "Ignores the exception, allowing you to continue." 958 | new "Ignores the exception, allowing you to continue." 959 | 960 | # renpy/common/_errorhandling.rpym:615 961 | old "Ignores the exception, allowing you to continue. This often leads to additional errors." 962 | new "Ignores the exception, allowing you to continue. This often leads to additional errors." 963 | 964 | # renpy/common/_errorhandling.rpym:619 965 | old "Reload" 966 | new "Reload" 967 | 968 | # renpy/common/_errorhandling.rpym:621 969 | old "Reloads the game from disk, saving and restoring game state if possible." 970 | new "Reloads the game from disk, saving and restoring game state if possible." 971 | 972 | # renpy/common/_errorhandling.rpym:624 973 | old "Console" 974 | new "Console" 975 | 976 | # renpy/common/_errorhandling.rpym:626 977 | old "Opens a console to allow debugging the problem." 978 | new "Opens a console to allow debugging the problem." 979 | 980 | # renpy/common/_errorhandling.rpym:639 981 | old "Quits the game." 982 | new "Quits the game." 983 | 984 | # renpy/common/_errorhandling.rpym:660 985 | old "Parsing the script failed." 986 | new "Parsing the script failed." 987 | 988 | # renpy/common/_errorhandling.rpym:686 989 | old "Opens the errors.txt file in a text editor." 990 | new "Opens the errors.txt file in a text editor." 991 | 992 | # renpy/common/_errorhandling.rpym:690 993 | old "Copies the errors.txt file to the clipboard as BBcode for forums like https://lemmasoft.renai.us/." 994 | new "Copies the errors.txt file to the clipboard as BBcode for forums like https://lemmasoft.renai.us/." 995 | 996 | # renpy/common/_errorhandling.rpym:694 997 | old "Copies the errors.txt file to the clipboard as Markdown for Discord." 998 | new "Copies the errors.txt file to the clipboard as Markdown for Discord." 999 | 1000 | # renpy/common/_developer/developer.rpym:38 1001 | old "Developer Menu" 1002 | new "Developer Menu" 1003 | 1004 | # renpy/common/_developer/developer.rpym:43 1005 | old "Interactive Director (D)" 1006 | new "Interactive Director (D)" 1007 | 1008 | # renpy/common/_developer/developer.rpym:45 1009 | old "Reload Game (Shift+R)" 1010 | new "Reload Game (Shift+R)" 1011 | 1012 | # renpy/common/_developer/developer.rpym:47 1013 | old "Console (Shift+O)" 1014 | new "Console (Shift+O)" 1015 | 1016 | # renpy/common/_developer/developer.rpym:49 1017 | old "Variable Viewer" 1018 | new "Variable Viewer" 1019 | 1020 | # renpy/common/_developer/developer.rpym:51 1021 | old "Image Location Picker" 1022 | new "Image Location Picker" 1023 | 1024 | # renpy/common/_developer/developer.rpym:53 1025 | old "Filename List" 1026 | new "Filename List" 1027 | 1028 | # renpy/common/_developer/developer.rpym:57 1029 | old "Show Image Load Log (F4)" 1030 | new "Show Image Load Log (F4)" 1031 | 1032 | # renpy/common/_developer/developer.rpym:60 1033 | old "Hide Image Load Log (F4)" 1034 | new "Hide Image Load Log (F4)" 1035 | 1036 | # renpy/common/_developer/developer.rpym:63 1037 | old "Image Attributes" 1038 | new "Image Attributes" 1039 | 1040 | # renpy/common/_developer/developer.rpym:90 1041 | old "[name] [attributes] (hidden)" 1042 | new "[name] [attributes] (hidden)" 1043 | 1044 | # renpy/common/_developer/developer.rpym:94 1045 | old "[name] [attributes]" 1046 | new "[name] [attributes]" 1047 | 1048 | # renpy/common/_developer/developer.rpym:143 1049 | old "Nothing to inspect." 1050 | new "Nothing to inspect." 1051 | 1052 | # renpy/common/_developer/developer.rpym:154 1053 | old "Hide deleted" 1054 | new "Hide deleted" 1055 | 1056 | # renpy/common/_developer/developer.rpym:154 1057 | old "Show deleted" 1058 | new "Show deleted" 1059 | 1060 | # renpy/common/_developer/developer.rpym:278 1061 | old "Return to the developer menu" 1062 | new "Return to the developer menu" 1063 | 1064 | # renpy/common/_developer/developer.rpym:443 1065 | old "Rectangle: %r" 1066 | new "Rectangle: %r" 1067 | 1068 | # renpy/common/_developer/developer.rpym:448 1069 | old "Mouse position: %r" 1070 | new "Mouse position: %r" 1071 | 1072 | # renpy/common/_developer/developer.rpym:453 1073 | old "Right-click or escape to quit." 1074 | new "Right-click or escape to quit." 1075 | 1076 | # renpy/common/_developer/developer.rpym:485 1077 | old "Rectangle copied to clipboard." 1078 | new "Rectangle copied to clipboard." 1079 | 1080 | # renpy/common/_developer/developer.rpym:488 1081 | old "Position copied to clipboard." 1082 | new "Position copied to clipboard." 1083 | 1084 | # renpy/common/_developer/developer.rpym:506 1085 | old "Type to filter: " 1086 | new "Type to filter: " 1087 | 1088 | # renpy/common/_developer/developer.rpym:631 1089 | old "Textures: [tex_count] ([tex_size_mb:.1f] MB)" 1090 | new "Textures: [tex_count] ([tex_size_mb:.1f] MB)" 1091 | 1092 | # renpy/common/_developer/developer.rpym:635 1093 | old "Image cache: [cache_pct:.1f]% ([cache_size_mb:.1f] MB)" 1094 | new "Image cache: [cache_pct:.1f]% ([cache_size_mb:.1f] MB)" 1095 | 1096 | # renpy/common/_developer/developer.rpym:645 1097 | old "✔ " 1098 | new "✔ " 1099 | 1100 | # renpy/common/_developer/developer.rpym:648 1101 | old "✘ " 1102 | new "✘ " 1103 | 1104 | # renpy/common/_developer/developer.rpym:653 1105 | old "\n{color=#cfc}✔ predicted image (good){/color}\n{color=#fcc}✘ unpredicted image (bad){/color}\n{color=#fff}Drag to move.{/color}" 1106 | new "\n{color=#cfc}✔ predicted image (good){/color}\n{color=#fcc}✘ unpredicted image (bad){/color}\n{color=#fff}Drag to move.{/color}" 1107 | 1108 | # renpy/common/_developer/inspector.rpym:38 1109 | old "Displayable Inspector" 1110 | new "Displayable Inspector" 1111 | 1112 | # renpy/common/_developer/inspector.rpym:61 1113 | old "Size" 1114 | new "Size" 1115 | 1116 | # renpy/common/_developer/inspector.rpym:65 1117 | old "Style" 1118 | new "Style" 1119 | 1120 | # renpy/common/_developer/inspector.rpym:71 1121 | old "Location" 1122 | new "Location" 1123 | 1124 | # renpy/common/_developer/inspector.rpym:122 1125 | old "Inspecting Styles of [displayable_name!q]" 1126 | new "Inspecting Styles of [displayable_name!q]" 1127 | 1128 | # renpy/common/_developer/inspector.rpym:139 1129 | old "displayable:" 1130 | new "displayable:" 1131 | 1132 | # renpy/common/_developer/inspector.rpym:145 1133 | old " (no properties affect the displayable)" 1134 | new " (no properties affect the displayable)" 1135 | 1136 | # renpy/common/_developer/inspector.rpym:147 1137 | old " (default properties omitted)" 1138 | new " (default properties omitted)" 1139 | 1140 | # renpy/common/_developer/inspector.rpym:185 1141 | old "" 1142 | new "" 1143 | 1144 | # renpy/common/00console.rpy:492 1145 | old "Press to exit console. Type help for help.\n" 1146 | new "Press to exit console. Type help for help.\n" 1147 | 1148 | # renpy/common/00console.rpy:496 1149 | old "Ren'Py script enabled." 1150 | new "Ren'Py script enabled." 1151 | 1152 | # renpy/common/00console.rpy:498 1153 | old "Ren'Py script disabled." 1154 | new "Ren'Py script disabled." 1155 | 1156 | # renpy/common/00console.rpy:745 1157 | old "help: show this help" 1158 | new "help: show this help" 1159 | 1160 | # renpy/common/00console.rpy:750 1161 | old "commands:\n" 1162 | new "commands:\n" 1163 | 1164 | # renpy/common/00console.rpy:760 1165 | old " : run the statement\n" 1166 | new " : run the statement\n" 1167 | 1168 | # renpy/common/00console.rpy:762 1169 | old " : run the expression or statement" 1170 | new " : run the expression or statement" 1171 | 1172 | # renpy/common/00console.rpy:770 1173 | old "clear: clear the console history" 1174 | new "clear: clear the console history" 1175 | 1176 | # renpy/common/00console.rpy:774 1177 | old "exit: exit the console" 1178 | new "exit: exit the console" 1179 | 1180 | # renpy/common/00console.rpy:782 1181 | old "load : loads the game from slot" 1182 | new "load : loads the game from slot" 1183 | 1184 | # renpy/common/00console.rpy:795 1185 | old "save : saves the game in slot" 1186 | new "save : saves the game in slot" 1187 | 1188 | # renpy/common/00console.rpy:806 1189 | old "reload: reloads the game, refreshing the scripts" 1190 | new "reload: reloads the game, refreshing the scripts" 1191 | 1192 | # renpy/common/00console.rpy:814 1193 | old "watch : watch a python expression\n watch short: makes the representation of traced expressions short (default)\n watch long: makes the representation of traced expressions as is" 1194 | new "watch : watch a python expression\n watch short: makes the representation of traced expressions short (default)\n watch long: makes the representation of traced expressions as is" 1195 | 1196 | # renpy/common/00console.rpy:849 1197 | old "unwatch : stop watching an expression" 1198 | new "unwatch : stop watching an expression" 1199 | 1200 | # renpy/common/00console.rpy:884 1201 | old "unwatchall: stop watching all expressions" 1202 | new "unwatchall: stop watching all expressions" 1203 | 1204 | # renpy/common/00console.rpy:901 1205 | old "jump