[Solved] Extras gallery button not defined

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Ayael
Regular
Posts: 82
Joined: Fri Apr 07, 2017 2:17 pm
Projects: Imperial Grace (on going), Autumn Spirit, Ballads at Midnight
Contact:

[Solved] Extras gallery button not defined

#1 Post by Ayael »

Hello, I tried to follow, this EXCELLENT tutorial (viewtopic.php?f=51&t=50040&p=511085#p511085) to create my own CG gallery, but, even so I didn't touch a single line of the code he gives, I have this error :

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/extras.rpy", line 166, in execute
    screen imagegallery():
  File "game/extras.rpy", line 166, in execute
    screen imagegallery():
  File "game/extras.rpy", line 168, in execute
    use exgame_menu(scroll="viewport"):
  File "game/extras.rpy", line 124, in execute
    screen exgame_menu(scroll=None, yinitial=0.0):
  File "game/extras.rpy", line 124, in execute
    screen exgame_menu(scroll=None, yinitial=0.0):
  File "game/extras.rpy", line 127, in execute
    frame:
  File "game/extras.rpy", line 129, in execute
    hbox:
  File "game/extras.rpy", line 132, in execute
    frame:
  File "game/extras.rpy", line 134, in execute
    if scroll == "viewport":
  File "game/extras.rpy", line 135, in execute
    viewport:
  File "game/extras.rpy", line 141, in execute
    vbox:
  File "game/extras.rpy", line 142, in execute
    transclude
  File "game/extras.rpy", line 168, in execute
    use exgame_menu(scroll="viewport"):
  File "game/extras.rpy", line 169, in execute
    grid 3 6:
  File "game/extras.rpy", line 174, in execute
    add g.make_button("cg_gallery01","images/thumbnails/thumbnail01.png")
  File "renpy/common/00gallery.rpy", line 377, in make_button
    action = self.Action(name)
  File "renpy/common/00gallery.rpy", line 330, in Action
    raise Exception("{0!r} is not a button defined in this gallery.".format(name))
Exception: u'cg_gallery01' is not a button defined in this gallery.

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/_layout/screen_main_menu.rpym", line 28, in script
    python hide:
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\ast.py", line 900, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1930, in py_exec_bytecode
    exec bytecode in globals, locals
  File "renpy/common/_layout/screen_main_menu.rpym", line 28, in <module>
    python hide:
  File "renpy/common/_layout/screen_main_menu.rpym", line 35, in _execute_python_hide
    ui.interact()
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\ui.py", line 289, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 2690, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 3074, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 534, in visit_all
    d.visit_all(callback, seen)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 534, in visit_all
    d.visit_all(callback, seen)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 534, in visit_all
    d.visit_all(callback, seen)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 534, in visit_all
    d.visit_all(callback, seen)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\screen.py", line 424, in visit_all
    callback(self)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\core.py", line 3074, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\screen.py", line 434, in per_interact
    self.update()
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\display\screen.py", line 619, in update
    self.screen.function(**self.scope)
  File "game/extras.rpy", line 166, in execute
    screen imagegallery():
  File "game/extras.rpy", line 166, in execute
    screen imagegallery():
  File "game/extras.rpy", line 168, in execute
    use exgame_menu(scroll="viewport"):
  File "game/extras.rpy", line 124, in execute
    screen exgame_menu(scroll=None, yinitial=0.0):
  File "game/extras.rpy", line 124, in execute
    screen exgame_menu(scroll=None, yinitial=0.0):
  File "game/extras.rpy", line 127, in execute
    frame:
  File "game/extras.rpy", line 129, in execute
    hbox:
  File "game/extras.rpy", line 132, in execute
    frame:
  File "game/extras.rpy", line 134, in execute
    if scroll == "viewport":
  File "game/extras.rpy", line 135, in execute
    viewport:
  File "game/extras.rpy", line 141, in execute
    vbox:
  File "game/extras.rpy", line 142, in execute
    transclude
  File "game/extras.rpy", line 168, in execute
    use exgame_menu(scroll="viewport"):
  File "game/extras.rpy", line 169, in execute
    grid 3 6:
  File "game/extras.rpy", line 174, in execute
    add g.make_button("cg_gallery01","images/thumbnails/thumbnail01.png")
  File "<screen language>", line 174, in <module>
  File "renpy/common/00gallery.rpy", line 377, in make_button
    action = self.Action(name)
  File "renpy/common/00gallery.rpy", line 330, in Action
    raise Exception("{0!r} is not a button defined in this gallery.".format(name))
Exception: u'cg_gallery01' is not a button defined in this gallery.

Windows-8-6.2.9200
Ren'Py 7.2.2.491
Anoldor_Edwyn 1.0
Fri May 17 21:36:07 2019
Error, I really doesn't understand, since the cg_gallery01 it is definitely define in the code :

Code: Select all

g = Gallery()
    g.button("cg_gallery01")
    g.image("image1")
    g.unlock("image1")
(Plus I was wandering how the "line 330" can have an error on it considering, there is only 290 lines in the code... :?: )

As always, thank you very much for your help!
Last edited by Ayael on Sat May 18, 2019 3:36 am, edited 1 time in total.
Image Image

User avatar
mitoky
Veteran
Posts: 316
Joined: Sat Feb 07, 2015 9:12 pm
Projects: The Purring Demon's Love, circus eterie
Contact:

Re: Extras gallery button not defined

#2 Post by mitoky »

Could you please paste your code here onto the site? You said its from the tutorial, but specifically to find the issue in your code, we need to see your whole code to find out what the problem exactly is.

But i think the issue is the part you posted, it should be like this:

Code: Select all

init python:
    g = Gallery()
    g.button("cg_gallery01")
    g.image("image1")
    g.unlock("image1")
Anyways, first fix that and afterwards, if the problem still persists, paste your code. I hope that solves the issue though (:
Last edited by mitoky on Fri May 17, 2019 4:29 pm, edited 1 time in total.

Ayael
Regular
Posts: 82
Joined: Fri Apr 07, 2017 2:17 pm
Projects: Imperial Grace (on going), Autumn Spirit, Ballads at Midnight
Contact:

Re: Extras gallery button not defined

#3 Post by Ayael »

Hi, thank you to look at my problem !
Sure, but as I said, I didn't change anything from it, so it must be the same than the file we can download.

Anyway, here it is :

Code: Select all

#### EXTRA SCREENS

# Put there the image gallery buttons and music gallery definitions
init python:
    mg= MusicRoom()
    mg.add("track1.ogg", always_unlocked=True)
    mg.add("track2.ogg")
    mg.add("track3.ogg")
    
    g = Gallery()
    g.button("cg_gallery01")
    g.image("image1")
    g.unlock("image1")
    
    g.button("cg_gallery02")
    g.image("image2")
    g.unlock("image2")
    
    g.button("cg_gallery03")
    g.image("image3")
    g.unlock("image3")
    
    g.button("cg_gallery04")
    g.image("image4")
    g.unlock("image4")
    
    g.button("cg_gallery05")
    g.image("image5")
    g.unlock("image5")
    
    g.button("cg_gallery06")
    g.image("image6")
    g.unlock("image6")
    
    g.button("cg_gallery07")
    g.image("image7")
    g.unlock("image7")
    
    g.button("cg_gallery08")
    g.image("image8")
    g.unlock("image8")
    
    g.button("cg_gallery09")
    g.image("image9")
    g.unlock("image9")
    
    g.button("cg_gallery10")
    g.image("image10")
    g.unlock("image10")
    
    g.button("cg_gallery11")
    g.image("image11")
    g.unlock("image11")
    
    g.button("cg_gallery12")
    g.image("image12")
    g.unlock("image12")
    
    g.button("cg_gallery13")
    g.image("image13")
    g.unlock("image13")
    
    g.button("cg_gallery14")
    g.image("image14")
    g.unlock("image14")
    
    g.button("cg_gallery15")
    g.image("image15")
    g.unlock("image15")
    
    g.button("cg_gallery16")
    g.image("image16")
    g.unlock("image16")
    
    g.button("cg_gallery17")
    g.image("image17")
    g.unlock("image17")
    
    g.button("cg_gallery18")
    g.image("image18")
    g.unlock("image18")
 
    g.locked_button=("images/thumbnails/thumbnail_locked.png")
    
default awards=[
    ["FIRST ENDING","Reach the first ending of the game","persistent.ending1==True"],
    ["Gas HERO","Positively comment on the author of the gallery","persistent.ending2==True"],
    ["WORLD SAVER","Save the world by decreasing pollution","persistent.ending3==True"]]
    
    
## Navigation screen ###########################################################
screen exnavi():
    vbox:
        style_prefix "navigation"
        xpos gui.navigation_xpos
        yalign 0.5
        spacing gui.navigation_spacing
        textbutton _("Images") action ShowMenu("imagegallery")
        textbutton _("Scenes") action ShowMenu("scenegallery")
        textbutton _("Awards") action ShowMenu("awardsgallery")
        
## The audio player on top of the screen ########################################
screen mp3():
    frame:
        xalign 1.0
        hbox:
            spacing 5
            textbutton "PREV" action mg.Previous()
            textbutton "PLAY" action mg.Play()
            textbutton "STOP" action mg.Stop()
            textbutton "NEXT" action mg.Next()
            frame:
                background None
                xsize 150
                $ titletrack=renpy.music.get_playing()
                if titletrack:
                    $ titletrack=titletrack[:len(titletrack)-4]
                    $ titletrack=titletrack.replace("_"," ")
                    $ titletrack=titletrack.title()
                    text "[titletrack]" xalign 0.5
                else:
                    null
## EXTRA Menu screen ############################################################
screen exgame_menu(scroll=None, yinitial=0.0):
    style_prefix "game_menu"
    add gui.game_menu_background
    frame:
        style "game_menu_outer_frame"
        hbox:
            frame:
                style "game_menu_navigation_frame"
            frame:
                style "game_menu_content_frame"
                if scroll == "viewport":
                    viewport:
                        yinitial yinitial
                        scrollbars "vertical"
                        mousewheel True
                        draggable True
                        side_yfill True
                        vbox:
                            transclude
                elif scroll == "vpgrid":
                    vpgrid:
                        cols 1
                        yinitial yinitial
                        scrollbars "vertical"
                        mousewheel True
                        draggable True
                        side_yfill True
                        transclude
                else:
                    transclude
                
    use exnavi
    label "Extra"
    textbutton _("Return"):
        style "return_button"
        action Return()

    if main_menu:
        key "game_menu" action ShowMenu("main_menu")
    use mp3

### IMAGE GALLERY! ##########################################
screen imagegallery():
    tag menu
    use exgame_menu(scroll="viewport"):
        grid 3 6:
            style_prefix "gslot"
            xalign 0.5
            yalign 0.5
            spacing gui.slot_spacing
            add g.make_button("cg_gallery01","images/thumbnails/thumbnail01.png")
            add g.make_button("cg_gallery02","images/thumbnails/thumbnail02.png")
            add g.make_button("cg_gallery03","images/thumbnails/thumbnail03.png")
            add g.make_button("cg_gallery04","images/thumbnails/thumbnail04.png")
            add g.make_button("cg_gallery05","images/thumbnails/thumbnail05.png")
            add g.make_button("cg_gallery06","images/thumbnails/thumbnail06.png")
            add g.make_button("cg_gallery07","images/thumbnails/thumbnail07.png")
            add g.make_button("cg_gallery08","images/thumbnails/thumbnail08.png")
            add g.make_button("cg_gallery09","images/thumbnails/thumbnail09.png")
            add g.make_button("cg_gallery10","images/thumbnails/thumbnail10.png")
            add g.make_button("cg_gallery11","images/thumbnails/thumbnail11.png")
            add g.make_button("cg_gallery12","images/thumbnails/thumbnail12.png")
            add g.make_button("cg_gallery13","images/thumbnails/thumbnail13.png")
            add g.make_button("cg_gallery14","images/thumbnails/thumbnail14.png")
            add g.make_button("cg_gallery15","images/thumbnails/thumbnail15.png")
            add g.make_button("cg_gallery16","images/thumbnails/thumbnail16.png")
            add g.make_button("cg_gallery17","images/thumbnails/thumbnail17.png")
            add g.make_button("cg_gallery18","images/thumbnails/thumbnail18.png")
style gslot:
    xsize 256
    ysize 144
### SCENE GALLERY! ##########################################
screen scenegallery():
    tag menu
    use exgame_menu(scroll="viewport"):
        grid 3 3:
            style_prefix "gslot"
            xalign 0.5
            yalign 0.5
            spacing gui.slot_spacing
            ## scene 1
            if renpy.seen_label("scene1"):
                imagebutton idle "images/thumbnails/scene1.png" action Replay("scene1")
            else:
                add "images/thumbnails/thumbnail_locked.png"
                
            ## scene 2
            if renpy.seen_label("scene2"):
                imagebutton idle "images/thumbnails/scene2.png" action Replay("scene2")
            else:
                add "images/thumbnails/thumbnail_locked.png"
                
            ## scene 3
            if renpy.seen_label("scene3"):
                imagebutton idle "images/thumbnails/scene3.png" action Replay("scene3")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 4
            if renpy.seen_label("scene4"):
                imagebutton idle "images/thumbnails/scene4.png" action Replay("scene4")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 5
            if renpy.seen_label("scene5"):
                imagebutton idle "images/thumbnails/scene5.png" action Replay("scene5")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 6
            if renpy.seen_label("scene6"):
                imagebutton idle "images/thumbnails/scene6.png" action Replay("scene6")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 7
            if renpy.seen_label("scene7"):
                imagebutton idle "images/thumbnails/scene7.png" action Replay("scene7")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 7
            if renpy.seen_label("scene8"):
                imagebutton idle "images/thumbnails/scene8.png" action Replay("scene8")
            else:
                add "images/thumbnails/thumbnail_locked.png"
            
            ## scene 9
            # well, there isn't so to fill the grid, a null
            null
### AWARDS GALERY! ###########################################
screen awardsgallery():
    tag menu
    use exgame_menu(scroll="viewport"):
        vbox:
            spacing gui.slot_spacing
            for i in range(len(awards)):
                $ verify=awards[i][2]
                $ eltitle=awards[i][0]
                $ eldesc=awards[i][1]
                frame:
                    yfill False
                    xfill True
                    padding (10,10,10,10)
                    has hbox
                    spacing gui.slot_spacing
                    if eval(verify)==True:
                        frame:
                            background None
                            xsize 100
                            text "!!!"
                        frame:
                            background None
                            xsize 200
                            text "[eltitle]" color gui.accent_color
                        text "[eldesc]" color gui.text_color yalign 0.5 size 22
                    else:
                        frame:
                            background None
                            xsize 100
                            null
                        frame:
                            background None
                            xsize 200
                            text "[eltitle]" color "#666"
                        text "[eldesc]" color "#999" yalign 0.5 size 22                
                    
        
Image Image

User avatar
mitoky
Veteran
Posts: 316
Joined: Sat Feb 07, 2015 9:12 pm
Projects: The Purring Demon's Love, circus eterie
Contact:

Re: Extras gallery button not defined

#4 Post by mitoky »

Hmm thats weird, it should recognize it. Can you try deleting your persistent data maybe?

EDIT: Also, did you copy/paste it into your screen.rpy at the end or where in your files is that part? Nvm, i just cant read xD

Ayael
Regular
Posts: 82
Joined: Fri Apr 07, 2017 2:17 pm
Projects: Imperial Grace (on going), Autumn Spirit, Ballads at Midnight
Contact:

Re: Extras gallery button not defined

#5 Post by Ayael »

Thank you again for your help !

I try to remove all persistent data from my game (script + extras) it didn't change anything.

BUT, I noticed, when I try to reload the game, I have this error, maybe it's linked ?

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00start.rpy", line 203, in script call
    call _load_reload_game from _call__load_reload_game_1
  File "renpy/common/00keymap.rpy", line 450, in script
    python hide:
  File "renpy/common/00keymap.rpy", line 450, in <module>
    python hide:
  File "renpy/common/00keymap.rpy", line 460, in _execute_python_hide
    renpy.load("_reload-2")
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/00start.rpy", line 203, in script call
    call _load_reload_game from _call__load_reload_game_1
  File "renpy/common/00keymap.rpy", line 450, in script
    python hide:
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\ast.py", line 900, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1930, in py_exec_bytecode
    exec bytecode in globals, locals
  File "renpy/common/00keymap.rpy", line 450, in <module>
    python hide:
  File "renpy/common/00keymap.rpy", line 460, in _execute_python_hide
    renpy.load("_reload-2")
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\loadsave.py", line 753, in load
    log.unfreeze(roots, label="_after_load")
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1885, in unfreeze
    self.rollback(0, force=True, label=label, greedy=greedy, on_load=True)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1713, in rollback
    raise Exception("Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?")
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?

Windows-8-6.2.9200
Ren'Py 7.2.2.491
Anoldor_Edwyn 1.0
Fri May 17 22:52:24 2019
Image Image

User avatar
mitoky
Veteran
Posts: 316
Joined: Sat Feb 07, 2015 9:12 pm
Projects: The Purring Demon's Love, circus eterie
Contact:

Re: Extras gallery button not defined

#6 Post by mitoky »

Ayael wrote: Fri May 17, 2019 4:53 pm Thank you again for your help !

I try to remove all persistent data from my game (script + extras) it didn't change anything.

BUT, I noticed, when I try to reload the game, I have this error, maybe it's linked ?

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "renpy/common/00start.rpy", line 203, in script call
    call _load_reload_game from _call__load_reload_game_1
  File "renpy/common/00keymap.rpy", line 450, in script
    python hide:
  File "renpy/common/00keymap.rpy", line 450, in <module>
    python hide:
  File "renpy/common/00keymap.rpy", line 460, in _execute_python_hide
    renpy.load("_reload-2")
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "renpy/common/00start.rpy", line 203, in script call
    call _load_reload_game from _call__load_reload_game_1
  File "renpy/common/00keymap.rpy", line 450, in script
    python hide:
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\ast.py", line 900, in execute
    renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1930, in py_exec_bytecode
    exec bytecode in globals, locals
  File "renpy/common/00keymap.rpy", line 450, in <module>
    python hide:
  File "renpy/common/00keymap.rpy", line 460, in _execute_python_hide
    renpy.load("_reload-2")
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\loadsave.py", line 753, in load
    log.unfreeze(roots, label="_after_load")
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1885, in unfreeze
    self.rollback(0, force=True, label=label, greedy=greedy, on_load=True)
  File "D:\Documents\Anoldor 2019\renpy-7.2.2-sdk\renpy\python.py", line 1713, in rollback
    raise Exception("Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?")
Exception: Couldn't find a place to stop rolling back. Perhaps the script changed in an incompatible way?

Windows-8-6.2.9200
Ren'Py 7.2.2.491
Anoldor_Edwyn 1.0
Fri May 17 22:52:24 2019
I think that error appears when you reload the game when it open and the script changes in a way not able to roll back. Usually re-opening help!

Another thing you could try is copy/paste the whole code from the rpy file into the screens.rpy (at the very end) and to declare the images used in the gallery. Did you do that?
Example:

Code: Select all

image image1 = "images/image1.png"
image image2 = "images/image2.png"
## and so on

init python:    
    g = Gallery()
    g.button("cg_gallery01")
    g.image("image1")
    g.unlock("image1")

Ayael
Regular
Posts: 82
Joined: Fri Apr 07, 2017 2:17 pm
Projects: Imperial Grace (on going), Autumn Spirit, Ballads at Midnight
Contact:

Re: Extras gallery button not defined

#7 Post by Ayael »

I FOUND THE PROBLEM. I did many try with gallery earlier, and there is one other files I didn't delete on the game folder with gallery statement. I tried to remove it, and suddenly, it worked perfectly ! (Sometimes there is really stupid thing that bother us)

Thank you, your last saying enlighted me !
Image Image

User avatar
mitoky
Veteran
Posts: 316
Joined: Sat Feb 07, 2015 9:12 pm
Projects: The Purring Demon's Love, circus eterie
Contact:

Re: Extras gallery button not defined

#8 Post by mitoky »

Ayael wrote: Sat May 18, 2019 3:19 am I FOUND THE PROBLEM. I did many try with gallery earlier, and there is one other files I didn't delete on the game folder with gallery statement. I tried to remove it, and suddenly, it worked perfectly ! (Sometimes there is really stupid thing that bother us)

Thank you, your last saying enlighted me !
Glad the issue is solved (: Good luck on your game!

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], apocolocyntose, Google [Bot]