Adventure Game Design Doc Point Click
Introduction
So, you wanna make a Point & Click adventure game in Renpy, huh? Or, you think you'll use Renpy, but maybe another game engine is better – but you don't know that yet! Even more stressful, maybe your game's vision isn't really of the classic Point & Click genre – as it turns out, you may be leaning more towards an RPG with a little bit of story, or a visual novel with a little bit of button clicking…
Don't fear, friend! (I can call you "friend", right?) This first tutorial / essay / long-winded dissertation should help get you started in figuring out if Point & Click in Renpy is right for your game.
Defining Point & Click
First, let's break down some of the elements that make up the quintessential Point & Click game:
- Pointing: The mouse is the main form of interaction between the player and the game
- Clicking: Events are generally dependent on waiting for input from the player
Obviously, I'm being a little facetious, but the definition of Point & Click is overly broad on purpose. However, even from my basic breakdown, there are a few takeaways you should consider:
- There's no point in pointing unless there are things to point at
You generally want to make the best use of screen-space in order to maximize breadth potential. So, it's generally better to have 1 scene with 5 objects to click on than 5 scenes with only 1 object in each. Of course, there's a balance in maximizing breadth: You want enough scenes to make your world feel sufficiently large and expansive, but you also want enough going on within each scene so that your world doesn't feel empty. Here is where you want to consider whether there are enough interaction opportunities in your vision to actually justify doing Point & Click, and not something more narrative-driven or cinematic.
- It's all about the clicks
In short, clicking should be the action taken by the player for the vast majority of play time. While WASD controls and walking simulators aren't completely incompatible with Point & Click, one of the advantages of using the mouse to travel is that changing scenes should be almost-instant. (If you insist on making players wait for their character to reach the edge of the screen before making the scene transition, at least give them a skip option.) This brings up an additional note: Point & Click games generally do not assess motor control – it's not about how fast players can click the correct button. So, it's generally preferable to use turn-based mechanics over realtime mechanics – the gamestate should only advance each time players click on something with their mouse. That's not to say that you can't implement time-based mechanics or challenges in your puzzles; they just shouldn't be the main focus. Thus, here is where you want to consider whether your game's pacing and mechanic-structure would be better suited for an RPG or walking simulator.
Game Engines
So, now that you've determined whether your vision can still be called a Point & Click game, it's time to consider the game engine you want to build it in. (I'm assuming you're not enough of a masochist to build your own game engine, but hey, no kink-shaming from me!) Since my own project has a strong narrative tilt, I decided to build it in Renpy, a game engine primarily used to create visual novels. Built-in dialogue and branching functionality were my main requirements for my chosen game engine; however, yours may differ. For example, Renpy has limited graphics and audio manipulation capabilities, with 3D support almost non-existent. So, if you want to use 3D or animated assets in Renpy, you'll have to rely on other software to create everything pre-rendered. I can't claim to be an authoritative source on the strengths and weaknesses of the various game engines available to the public, so unfortunately I'll have to direct you to other websites so you can answer that question for yourself.
Structure
Now that you're confident that Renpy and Point & Click are right for you, let's finally get started! The general structure of any Point & Click project is going to look something like the following:
Enter Scene
In this step, you load the scene and all elements within it based on the current game state. This includes things like background images, sprites, and animations. Then, you check the game state and perform the appropriate reaction to the player's entrance into the scene. In some cases, there is no reaction, and you can go straight to enabling scene interactivity.
React to Entrance
In this step, you call any dialogue or cutscenes that should play immediately after the player enters the scene. For example, an NPC in the scene gives the player a greeting. In some cases, the reaction may be to kick the player out of the scene, skipping the next 3 steps and proceeding straight to updating the game state. For example, the player enters a room without any lights on, and the reaction is for the player character to say that they are too scared to stay in that room.
Enable Scene Interactivity
In this step, all appropriate click points within the scene are enabled, based on the game state. While you may have some animations and sounds looping in the background, the game state itself should remain paused until the player clicks on something. In some cases, you may add a timer to the scene, and if the player fails to click on anything before the timer runs out, you skip to the next reaction set using a random or predetermined player action. For example, the player is being chased by a monster, and can only stay in the room for 15 seconds. If the player doesn't click on another room to go to before the 15 seconds is up, a random room is selected. (In a darker version of this example, the monster eats the player!)
Player Points & Clicks
In this step, click points within the scene react to the player's cursor, and the game state remains paused until the player clicks on something or any timers run out. Cursor reactions include changing the appearance of click points when the cursor hovers over them, as well as changing the sprite used for the cursor itself. The player can also interact with objects outside of the scene. For example, the player can select items in their inventory, or check notes collected in their journal, without impacting the overall game state.
Call Reaction to Player
In this step, you call any dialogue or cutscenes that should play after the player clicks on something (or fails to click on something!) While you could skip this step for certain interactions, it is generally best practices to have *some* sort of response to player actions, even if it is something minimal like playing a sound effect.
Update Game State
In this step, variables affected by the player's most recent interaction are updated. In rare cases, you may have a click point that has no effect on the overall game state, but it's a good idea to include this step after every interaction. Additionally, you should always enter a scene after this step, even if it's the same scene that the player was in previously. This ensures that everything updates properly, and minimizes any recursion.
Implementation in Renpy
Alright, I think it's time we roll out a bit of Renpy code to get us started! We can begin with a default Renpy project, where Eileen is our default character. In your script.rpy file, you should add the following:
define e = Character("Eileen") default in_room = False default move_count = 0 default current_room = "LivingRoom" default previous_room = "" label start: e "Here is the start of your game." #Call the first scene $ current_room = "LivingRoom" call MyRoom e "You finished the game!" return label MyRoom: #Update values behind the scenes $ update_gamestate() #Enter the scene $ in_room = False $ renpy.show_screen(current_room + "Screen") #React to entrance if current_room != previous_room: $ check_intro_reactions(current_room) $ previous_room = current_room #Enable scene interactivity $ in_room = True $ renpy.call_screen(current_room + "Screen") return First, note that there are several functions that we haven't defined yet, so Renpy will throw an error if you try to run it as-is. Regardless, let's run through what this first bit does. I'm using a few variables that I initialize at the top using Renpy's "default" statement:
- in_room -> whether or not we should make the scene interactive (True or False)
- move_count -> the number of interactions the player has made (basically the game's clock)
- current_room -> the name of the scene that the player is in (don't use spaces!)
- previous_room -> the name of the previous scene that the player was in
After these variables are initialized, we have the "start" label, which is where the game moves to after the player starts a new game. Our character Eileen says a line of dialogue, and then we start the action by setting the current room and calling the label "MyRoom". Note that since we are calling the label (instead of jumping), we create a new call in the stack. This means that whenever we hit the next "return" statement under a label, we will return to the next line after "call MyRoom". At that point, Eileen will say another line of dialogue, and then the game will end, returning back to the main menu.
Now for the fun stuff! Under the label "MyRoom", we start implementing the structure I talked about previously. First, we update the game state (see further down for the code.) Then, we enter the scene. Since we don't want the player to be able to interact quite yet, we set "in_room" to False. Then, we show the screen for the room. The name of the screen will be our current room name with "Screen" added to the end, so for the first screen, it will be "LivingRoomScreen".
After our screen is shown, we check whether the player has entered a new room, and if the current room is not the same as the previous room, we call any reactions to the player's entrance (see further down for the code.) Afterwards, we set "previous_room" equal to "current_room". Then, to ensure our screen is interactive, we set "in_room" to True, and then we call our screen. Note that when we call the screen (instead of showing it), the game pauses and waits for the screen to return before continuing. (The screen will return when we call an action that closes the screen. However we won't be calling any actions that actually bring us to that final "return" under the "MyRoom" label.)
Now, let's define our screens. I suggest creating a new *.rpy file to put this in.
screen LivingRoomScreen(): vbox: text "Living Room" text "Move Count: " + str(move_count) textbutton "Go to Dining Room": action [SensitiveIf(in_room), SetVariable("current_room", "DiningRoom"), Jump("MyRoom")] textbutton "End Game": action [SensitiveIf(in_room), Jump("EndGame")] screen DiningRoomScreen(): vbox: text "Dining Room" text "Move Count: " + str(move_count) textbutton "Go to Living Room": action [SensitiveIf(in_room), SetVariable("current_room", "LivingRoom"), Jump("MyRoom")] textbutton "Look at Dinner": action [SensitiveIf(in_room), Jump("LookAtDinner")] So far, we have two screens: LivingRoomScreen and DiningRoomScreen. You can put whatever you want into each of these; however, to keep things simple, I've only added some text that displays the name of the room and 2 text-buttons.
For the living room, I first created a vertical box to keep everything neat. By default, items within the vbox will be aligned to the top left of the screen, with each additional item added below the previous one. So, the first item in the vbox is a text that displays "Living Room". The second item is another text that displays the number of moves that have taken place since the game started. For example, if 5 moves have taken place, the text will display "Move Count: 5". The next item is a text-button that displays "Go to Dining Room". The player should only be able to click on this button when "in_room" is True, so I used "SensitiveIf(in_room)" as one of the button actions. When the button is clicked, it should set "current_room" to "DiningRoom", and then jump to the label "MyRoom". For simplicity, I combined the "Call Reaction to Player" and "Update Game State" steps to take place within the button actions; however, in future tutorials, there will be some expansions and revisions. The final item in the Living Room vbox is another text-button that jumps to a new label "EndGame", which will be created in code below. Ultimately, clicking this button will allow the player to return back to the point where Eileen says "You finished the game!"
For the dining room, I also used a vbox to keep everything neat. I display a text with "Dining Room" shown. Next, I display a text with the move count shown. Then, I added a text-button that sends the player to the living room. Finally, I added a text-button that sends the player to a new label "LookAtDinner".
Let's add these new labels to the script.rpy file:
label EndGame: e "Let's finish the game!" return label LookAtDinner: $ in_room = False $ renpy.show_screen(current_room + "Screen") e "Oooh! Looks like we're having pizza!" jump MyRoom
In the label "EndGame", Eileen says a line of dialogue, followed by a "return" statement. Note that when we jump to this label, our screen will disappear – that's ok! Since we've reached the end of the game, you'll probably want to show a different screen or have other things happen. In any case, when we hit the "return" statement, it will end the current call in the stack, which was created the first time we went to "MyRoom", and go to the line where Eileen says "You finished the game!"
In the label "LookAtDinner", we have a few more things going on. First, we set "in_room" to False since we don't want the player clicking on buttons right now. Next, since our screen was destroyed when we jumped to this label, we need to show it again. (Alternatively, you could show a different screen, like a close-up image of Eileen's dinner!) Then, Eileen says a line of dialogue. Finally, instead of returning, we jump back to the "MyRoom" label. Thus, this label represents the "Call Reaction to Player" step of the process.
Now, we have some other functions to implement. I suggest creating another new *.rpy file.
init python: def update_gamestate(): global move_count newcount = move_count + 1 SetVariable("move_count", newcount)() return def check_intro_reactions(room): if room == "LivingRoom": renpy.call("EnterLivingRoom") elif room == "DiningRoom": renpy.call("EnterDiningRoom") return Looks like we'll be adding even more labels now! Anyway, the first function "update_gamestate" just increments "move_count" by 1. To ensure that Renpy is properly notified when we update the "move_count" variable, we use the "SetVariable" function instead of saying "move_count += 1". If you don't do it this way, your screens might not update when they should!
The next function "check_intro_reactions" takes 1 argument – the name of the room that the player has entered. Currently, it compares "room" against our known room names "LivingRoom" and "DiningRoom", then calls the appropriate label (which we will code below.) Note that we are calling instead of jumping, because we want to return to where we called "check_intro_reactions" after these labels are finished.
So, let's add our new labels back to the script.rpy file:
label EnterLivingRoom: e "I just entered the living room!" return label EnterDiningRoom: e "I just entered the dining room!" return
Both labels are pretty basic stuff – Eileen says a line of dialogue, and then there is a "return" statement.
Ok, now we can test what we have so far!
As you can see, it's pretty barebones, but everything is functioning as intended. All the dialogue plays as it's supposed to. The buttons are disabled while dialogue is being shown. The move count updates before Eileen says that she entered the room. However, there is plenty of room for improvement! For starters, Eileen says the same thing every time she enters a room or checks out what's for dinner. In future tutorials, I'll discuss adding more complex functionality, and hopefully implement some of your requested features.
Let me know in the comments section whether you found this tutorial helpful, and definitely let me know if you encounter any bugs in my code! That's all for now…
~West
Adventure Game Design Doc Point Click
Source: https://westofentropy.wordpress.com/2020/10/29/renpy-point-and-click-tutorial-1-structure/
Posted by: petersoncousise.blogspot.com

0 Response to "Adventure Game Design Doc Point Click"
Post a Comment