#+TITLE: Game Concept
#+DESCRIPTION: Concept document for the 2d platform/adventure game demo we're creating as a base for the Kickstarter 2019 2d game creation course.
#+COLUMNS: %5TODO %25ITEM %1PRIORITY %8Effort(Effort){:} %TAGS
#+PROPERTY: Effort_ALL 0:30 1:00 1:30 2:00 3:00 4:00 6:00 8:00
#+AUTHOR: Nathan Lovato


* Gameplay

** Core mechanic: pulling yourself with the Hook

    You use a *hook* to propel yourself *instantly* towards hookable targets and navigate the world fluidly, often without touching the ground.

    The character's jump isn't powerful enough for you to reach most platforms. You mostly use it to hop over small gaps and obstacles, or to reach a hooking target that's slightly too far otherwise.

*** Possible other uses

      - *Pull objects* and enemies towards you. E.g. pull rocks blocking the way, make an enemy off balance...
      - Hold a button after throwing the hook to *propel the character like a cannon ball* and jump past the hooking point. Use it to go farther than usual or e.g. to break weak surfaces
      - A blade so you can *plant the hook in e.g. wooden surfaces*, but not rock. Be it to pull yourself towards new places, or to pull objects with the hook.
      - Use the hook as a *propeller* to glide over short distances
      - /Combat/
        - Pull shields or armor plates off enemies
        - Hit enemies from mid-range, using the hook as a whip with the blade
        - Charge onto enemies with the cannonball attack
        - Lunge down on enemies and stun them if falling from above

*** Controls

**** Mouse and keyboard

     Use the mouse to aim and to use the hook, the keyboard to move the character. Aim the hook with the mouse and ~<L-Mouse>~ to throw.

**** Gamepad

     The hook aims in the direction the player is moving, throw with the right bumper.

     - Note taken on [2019-05-01 mer. 07:39] \\
       I've tested different control schemes:

       - Using the right joystick to aim the hook. It's too hard to use other buttons along with both joysticks.
       - Using a key to toggle aiming the hook. Breaks the flow of the action.
       - Using the 4 ABXY keys to throw the hook in the corresponding direction. It works, but it limits the buttons left for other purposes, e.g. jump is typically on A on an XBOX controller.

       Aiming where the player moves feels most natural so far.

**** Snapping

     Regardless of the control scheme, use a snapping system to help direct the player towards hooking points. Even on rails or long hookable surfaces, we might want to have a limited number of points, e.g. in the middle and on the sides, to help the player better hook using a gamepad.

* Prototypes
** DONE Base movement with the hook
   CLOSED: [2019-05-03 ven. 10:18]

   Explore controls and game feel, allowing the player to move fluidly through template levels.

  #+caption: Movement prototype: raycast-based hook mechanic with snapping
  [[file:./img/prototypes/hook!-prototype-3.png]]

*** Questions

    1. How can we make the hook at the core of the platforming experience?
    2. Which control scheme would work with kbd and mouse? With the gamepad?
    3. How can we make the player feel both free in its movement while making the controls intuitive? Especially with the imprecise gamepad.

*** Answers from the prototype

    1. The jump should be weak compared to the hook.
    2. See [[*Controls][Controls]]
    3. I had to add a snapping system. Currently, it uses 2 Capsule shapes and a Raycast2D to detect snapping targets in the direction the player is looking (mouse) or moving (gamepad). It snaps to the closest target in that direction, meaning we should always space them. Also, upon hooking onto a point target, the target deactivates for a short amount of time, allowing you to hook onto the next target forward more reliably.

** DONE Experiment with control schemes for the gamepad
   CLOSED: [2019-05-03 ven. 13:19]

   Checkout to the ~gamepad_alternate_controls~ branch to test the controls.
   
   Henrique and another community member mentioned that only hooking in the direction the player is moving could take control away from the player. Although I did try alternate control schemes when creating the first prototype, 
   
*** Inspired by Ori's bash

   Use a key to stop or drastically slow down time and let the player aim with left stick. Instant hook upon hook input, or releasing the slow down time key?

*** Using twin sticks again

    I didn't like the feel of the twin stick controls as you can't use the ABXY keys at the same time, unless you take your thumb off the right joystick. This leaves you only with the bumpers and triggers as extra controls, and prevents you from using A to jump.
    
    However, if we use the ABXY keys only outside of the action, e.g. to grab an item in a safe environment, to open a door, or to start a dialogue, this would be fine. As the hook should have many purposes, we shouldn't need too many keys to use it.

*** Questions
    
    Can alternate input schemes retain the fluidity of the motion while giving the player more control?
    
*** Answers from the prototype
    
    Both approaches work. The slow down effect would need to be limited to retain some challenge in the motion, but using a single joystick to move in any direction is comfortable to me. We could limit it in a few ways:

    - Making it a resource that depletes and refills gradually, or by touching some object in the environment. E.g. flowers that emit essence of time. This would force the player to still be fast and use the mechanic sparingly.
    - Only allow the player to use it mid-air, once or twice only until the player touches the ground again. This would give you precise hook charges.

    The twin stick setup also works. To me, it feels more technical, and less accessible. But it works.

** TODO Unlocking behaviors and code structure
   :PROPERTIES:
   :EFFORT:   4:00
   :END:

   Figure out a good pattern/code structure to unlock and manage new moves on the playable character: e.g. wall-jump, new powers for the hook...

*** Questions

    1. Most moves rely on the hook and will revolve around the same base input, to make the core control as versatile as possible. How can we make it modular, allow ourselves to /hook/ new mechanics onto it?
    2. Can we find a pattern and code style that's both modular, i.e. uses aggregation, and that stays accessible to the students?
    3. Which code pattern would work best for Godot?

** DONE Test RigidBody2D instead of KinematicBody2D for the hook-based movement :guilherme:
   :PROPERTIES:
   :EFFORT:   3:00
   :END:
   
   We have two options to handle the character's motion: controlling the physics ourselves with ~KinematicBody2D~, or relying on the Bullet physics engine with ~RigidBody2D~.

   I expect that using Bullet will reduce our control on the character's motion, and that would lead to a different game feel and gameplay down the line: we could have the character hit objects and make them fall using physics, etc.
   
   It's worth trying only to see if we can't make a game that feels as good or to avoid some code-related challenges.
   
   You can use the existing hook mechanism almost as-is for this test, as it gives you a direction to hook to. The only element that has to change is the character.
   
   The goal is to see if we can build a good hook movement with rigidbody2d, as good as with KinematicBody2D. See the questions below.
   
*** Questions
    
    - What are the advantages of RigidBody2D in practice?
    - What are its drawbacks and limitations?
    - Is the code easier to write?

*** Test results
    
**** Using impulse for the hook
     
     /I took the notes in this section while creating the controller so we could have a better idea of some pitfalls I encountered/

     - Using RigidBody2D alone causes unexpected behaviors when the player is already moving
       - When falling and hooking upwards, the player keeps falling
       - Hooking towards the current move direction speeds the player up a lot
     - To fix the issues, setting the velocity to zero and then applying the impulse seems to do the trick
     - Switching back from air state seems to be a "challenge" since there's no easy way to check collisions and collision points. Raycasts were tested and they aren't a good option
     - No access to delta inside of ~_integrate_forces~, I believe it can lead to different player speeds in different computers
       - Since we are modifying the player's ~linear_velocity~ this has to be done inside of this function

**** Problems
     
     - Sometimes the player is not able to move for one frame after hitting the ground. Couldn't find a solution for this one
     - Found a bug with collision here:
       - [[https://i.imgur.com/rq1p8SL.png]]
       - I'm not sure what's causing it, neither what's the real problem. When the error is triggered, it's impossible to jump.

     Here's the error:
     
     #+BEGIN_SRC
     E 0:01:16:0371   Condition ' !area_in && !E ' is true.
     <C Source>     scene/2d/area_2d.cpp:264 @ _area_inout()
     #+END_SRC

**** Conclusion

     *Quick disclaimer:* I didn't look at razvan's code because I didn't want to get biased to go down the same route that he went, so maybe some of the problems that I found here could be fixed by his solution. 

     To me it seems that we are trying to make a ~RigidBody~ behave more as ~KinematicBody~ while trying to have more control over it. Also, if our final game is to have slopes, it might cause some problems as we won't be able to easily snap the player to them. There are more inherited problems that you have to fix than you would've if we went with a ~KinematicBody~. For my LD44 game there was also a simple hook mechanic and I used a ~KinematicBody~ and managed to put it together relatively quickly.

     We get some advantages because of the physics engine taking care of some things, like the impulse for the hook, but we lose a lot of responsiveness from the player controller itself. I believe that the ~RigidBody~ approach would be better if we wanted our player to _swing_ with the hook, as we would be able to use ~Joints~ along with it. But for what I've seen this is not the intent. It's also easier to control damping as it's taken care for us by the engine, but this isn't something super hard to achieve by code.

     I didn't want to spend too much time tweaking variables but I'm certain we could achieve better results by playing around with both the ~PhysicsMaterial~ and the ~RigidBody~'s properties - which is probably something we'll have to do for the "real" game, even if we go down the ~KinematicBody~ route. 

     It's also important to note that I was using [[https://store.steampowered.com/app/401710/Flinthook/][Flinthook]] as reference while creating the code. 
     
     #+BEGIN_QUOTE
     we could have the character hit objects and make them fall using physics, etc.
     #+END_QUOTE
     
     Can't this be achieved using a ~KinematicBody2D~? It's just not affected by physics, but it affects others bodies. 

** DONE Improving movement
   CLOSED: [2019-05-14 mar. 08:40]
   :PROPERTIES:
   :EFFORT:   4:00
   :END:
   
   The base movement is in place, but it does have some quirks. It's still easy to bump into a corner and to miss landing on a platform.
   
   Some issues:
   
   1. Hooking doesn't reliably pull you to the hooking point
      - Hooking to a node from up close barely pulls the character, making it not reach the hooking point.
      - Hooking downwards accelerates your fall and often makes you miss your target.
      - Hooking horizontally while falling doesn't slow down your descent, so it has almost no effect on your motion.
     
   2. The air state has a higher horizontal speed limit than when walking on the ground, so the character accelerates horizontally upon jumping.
      - The speed cap should be dynamic, depending on whether the player used the hook or not.
      - It's the hook that should provide a maximum speed boost?

   3. If the player misses getting on a platform by a small shot, we could have the character climb on it using the ledge.
      - The intention behind the design being to offer a fluid experience with motion, it's not fun to miss a platform by a few pixels, and the character being agile, it could make sense for it to climb ledges automatically.
      - The goal isn't to remove challenge or to babysit the player, but to have serious challenge in other parts of the level design/gameplay, and not break the flow of the motion for a small imprecision.
      - See Dead Cells for an example
   
*** Results

    The ledge state improves control quite a bit, it feels a lot more pleasant to have the character continue moving and not get stuck if you miss the platform by a few pixels.
    
    The character now slows down when hooking downwards during a fall. It makes it hop to the right or to the left, making the downward hook usable.
    
    There are fixes and improvements for all the points above, and overall it makes the controls feel more reliable and the motion feels more fluid to me. Now, we need to do level design work, get people to test the game and see how it works for them.
    
** DONE Design level loops
   CLOSED: [2019-05-31 ven. 08:50]
   :PROPERTIES:
   :EFFORT:   6:00
   :END:
   
   We have some core movement and controls in place. We now need to work on level design loops that we can combine to create complete rooms. E.g. having a ledge, a pit, and a distant platform down the character that's only accessible using the hook: the loop involves falling and using the hook mid-air going down.
   
   [[./img/prototypes/level-design-loops-illustration.png]]
   
   These loops should push the possibilities offered by the hook and explore ways to combine them. It's also an opportunity to figure out its limitations and ways to improve the movement.
   
   You can add new mechanics or obstacles as part of this, like moving platforms, but be sure to focus on level design and to try to reuse each element as much as possible.
   
   Use a new node branch for each chunk, and separate collision bodies so we can save the best ones as reusable scenes.
   
** DONE Refining the core movement
   CLOSED: [2019-05-31 ven. 08:51]
   
   After testing the level design work from Henrique, some problems with the game's controls are clearer:

   - It's hard to catch a hook at times, as the character falls fast. You have to be too reactive with the input.
   - The camera doesn't help enough in seeing the challenges ahead, especially with vertical level design.

   This prototype is an attempt at solving these issues:
   
   - Camera design: the lookahead based on the mouse's position makes the camera jiggle too much. We've got to experiment working with the input direction and move direction of the character. Using the velocity alone makes it so the camera lags behind, while updating based on input instantly almost gives motion sickness.
   - Store input: jump after fall start, or hook
   - Allow the player to jump right after a fall started, and to hook if the input was right before actually the snap detector detected the hooking point. Maybe only when falling?

* Course

** Teaching goals
   
*** Game design

   - *Using one mechanic for many purposes*: giving the player a versatile tool.
   - *Game feel*: making the game feel alive by adding life and feedback to the environment and the player's actions

*** Game creation

    - *Game creation workflow*: the process and broad steps to follow to get a game project started, prototyping, and getting the character controller, camera, etc. to feel right.
    - *Making multiple behaviors interact together*: especially for the character controller, getting the different moves (/e.g. jump, wall jump, slide/) to flawlessly flow into one another.

*** Metroidvania essentials

    - *Platforming character controller* and related code structure: behaviors, aggregation-based approach.
    - *Level design*, creation workflow, and connecting frames. Guiding the player through the environment, looping, and branching paths.
    - *Unlocking mechanics* through upgrades and controlling player progression.
    - *Camera*: helping the player with a camera that moves ahead of the character and looks where the player wants to look.

** List of topics
 
   /This is a list of topics that can be broken down or merged into more or fewer videos. From there, we should arrange them to form the 3 series (free, indie, pro) with clearer lists of topics and videos, and refine as we move forward with the project's pre-production./
   
   /This isn't a list of videos for the course: we should pick the scope from there./
   
   # Remember for teaching: copy paste code snippets instead of writing every line.
   # Check e.g. Brilliant for assignment examples and text-based resources.
   
*** Extra video ideas

    /Ideas of modules to extend the course/
    
   Collecting keys and opening closed doors
   Modular AI for enemies, different algorithms to find paths, flee the player...
   Porting an algorithm to C or C++ with NativeScript/GDNative. E.g. a heatmap algorithm would run slowly in GDScript
   Minimap: designing and implementing a map that updates as you explore new frames, and that can show unexplored areas
   
**** Creating tools for debugging and testing the game efficiently
     
     Series on designing and creating good tools, be it in the viewport, as in the waypoint platform tutorial, or in-game, like a tool to fly through the world.
     
     Tools should always answer a need: figure out what costs you or what's going to cost you time, prioritize them, figure out solutions, and calculate the time they'd take you.
     Tools for level design/testing/free camera
     Tools for code/debug code
     
**** Boss
     
     Designing and implementing a boss, with an intro and outro cut-scene, and phases.
     
** Free series

   Create a simple yet compelling platform game, learning the creation workflow from an indie game dev's perspective.
   
*** Intro: what this course is about, what you'll learn, how to make the most of it
   
    Target audience
    Pre-requisites
    What you'll learn: list of content
    How this course is designed/teaching style
    Free resources to get up to speed
    
*** How to make video games: getting started
    
    *Goal*: Learn what it takes to make games when you have no experience, and how you can get started

    - Overview of the process
    - Avoiding common pitfalls as a beginner
    - Reassure people about programming: it doesn't have to be hard, it can also be fun
    - Share practical resources to get started with Godot or GDevelop
    
      References:
   
      - https://www.youtube.com/watch?v=j48LtUkZRjU
      - https://www.youtube.com/watch?v=z06QR-tz1_o
      - Playlist by Extra credits https://www.youtube.com/watch?v=z06QR-tz1_o&list=PLhyKYa0YJ_5C6QC36h5eApOyXtx98ehGi
      
**** Intro
    
     You want to make video games, but you don't know how or where to start? In this video, you'll learn Everything you need to know to get started and create your first game.

     1. How indie developers make games
     2. Free Software you can use to create your own games
     3. Free resources and tutorials to get started

     I'm Nathan, and I've been teaching game creation and art for years, with Free Software like the Godot game engine and the digital painting app Krita.

**** Notes
     
     Make something that you can do at first
     Can I make a game without programming?
     
     No. But wait! Maybe programming isn't what you think.
     Changing values in the Inspector is programming.
     You can learn it slowly, start simple, and write more complicated code as you progress.

**** Summary

*** How it's like to work as a game designer: a day in the life of an indie game designer
    
*** How to make games: the workflow
    
    Cover the workflow to pre-produce, then produce a game, using the metroidvania 2d project as an example
    Only about creating the game: 
  
    Prototyping, experimenting
    You can only plan from production
  
*** Metroidvania design analysis: what makes a (good) Metroidvania?
    
    Take the analysis from the course's README/prototype jam doc
    
*** Basic motion and input: ground, air control
    
*** Basic hook mechanic
    
*** Simple lookahead camera: following the player's velocity
    
*** Creating a level with Tilemaps and scenes
    
*** Simple transition between two levels
    
*** Adding BGM and sounds to the game
    
*** Character health and taking damage on contact
    
*** Death and restarting the game

*** Basic patrol AI: detects gaps and walls, moves within a range
    
*** Integrating assets into the game
    
*** Building and distributing the game for desktop
   
    Publishing on Itch.io?
    
*** Bonus
    
**** Creating a game soundtrack with Free Software /Include the plugins, virtual instruments you found/ (beginner/introductory tut)
     
**** Doing sound design for your game with Free Software (beginner/introductory tut)

** Premium series
  
*** Indie
    
    /This is a list of topics, some can take several videos/
    
    Scaling the hook's power based on distance
    Wall jump
    Ledge detection, grab ledge, and let the player jump
    
    Unlocking new abilities
    
    Level loops: Exploring the possibilities of the core mechanic
    Designing frames with pre-made scenes, level loops, and tilemaps
    Teaching the player how to play through level design: designing an in-game tutorial without words
    
    Designing game animations in Godot
    
    Designing combat mechanics, damaging enemies: e.g. hook pulls character to enemy and kills it, enemies use projectiles?
    
    Simple flying enemy AI
    
    Hook: Pulling objects
    
    Sound design: how to choose the sounds and BGM for your game to improve the experience and game feel /Practical sound design tips like boosting basses, listening to the game the eyes closed.../
   
*** Pro
    
    /This is a list of topics, some can take several videos/
    
    Design analyses of character movement, camera, etc. in other platform games
    
    Ledge: teleport to the platform
    Polish: Storing input before touching the ground
    Polish: letting the player jump right after starting a fall
    
    Refining the camera: better prediction of the player's motion
    
    Hook: Breaking fragile surfaces
    Hook: Removing armors from enemies
    
    How to architecture the map at a meta level to manage the player's progression
    
    Designing and implementing flexible AI: Series on pathfinding, code structure to build reusable AI behaviors for flying enemies
    
    Code structure: Rundown of the project's code structure and abstractions
    Code structure: Patterns we use in the project
    
