Overview
Syllabus
Intro:
Importing assets and why pool?:
Setting up Billiard Table and import settings:
Reorganizing FileSystem structure:
Basic lighting and explaining 3D axes:
Setting up the Ball scene:
Auto-generating collision shapes versus making one manually:
Assigning material textures in the Inspector:
Assigning texture in the code:
Creating a unique material to fix shared references:
Deciding on how we should approach our gameplay system:
Setting up the play system and deciding on what script hits the ball:
Starting play system code with shooting the ball:
Aiming and stick system nodes 1 - fixing import orientation:
Aiming and stick system nodes 2 - positioning camera and stick:
Aiming and stick system nodes 3 - rotating around the ball:
Rotating around ball in code and understanding light versus heavy decisions
Organizing code with subroutines and hiding and fixing the mouse:
Aiming and stick system nodes 4 - manipulating nodes to optimize local space:
Moving stick within clamped positions in code:
Strongly typing, static typing, and the walrus operator:
Understanding basis to shoot the ball in the aim direction:
Using AnimationPlayer to tween stick shooting animation:
Hitting ball at the end of the animation:
Having variable starting animation key:
Communicating between different systems using custom signals:
Creating wall colliders for the playing surface:
Correcting bounce and deceleration with PhysicsMaterial and damping:
Implementing variable shot power using lerp:
Preventing wall clipping with physics step vs continuous collision detection:
Global values as class constants vs static variables vs object references:
Spawning balls and assigning respective textures in the code:
Procedurally spawning the balls in a triangular ball rack:
Using enumerators to establish ball types:
Setting a maximum y velocity to keep balls on the table surface:
Starting the gameplay finite state machine, booleans vs enums vs state pattern:
Deciding on way to check if all balls have stopped, for readability and scalability:
Establishing a readable, scalable system for processing the game rules:
Completing a player's turn with signals:
Considering which systems should set the play state:
Creating dynamic resources for sharing state instead of a global singleton:
Implementing the new game state resource to share state between systems:
Setting up the scene for table pockets:
Handling what happens when a ball has been potted by checking object identity:
Devising a cheat mode to make testing ball pocket rule test mechanics easier:
Working with physics engine quirky properties to stop a ball:
Setting up the HUD label nodes system and shared saved TextSettings:
Using a setter to emit whenever the play state has changed, and updating text:
Nested classes and subclasses to store what happened during a shot:
Setting up processing if a solid or stripes ball was potted during a shot:
Devising how to communicate which player is solids and which is stripes:
Forcing Godot to update to recognize new enum values
Checking and setting player suits while using some programming tricks:
Making rules process only under the correct state and with fresh occurrences:
Showing player suit in HUD by extracting the string names of the BallType enum:
Allowing player to keep their turn if they hit in a ball of their suit:
Setting up fouls and a placeholder for ball-in-hand mode, with basic debugging:
Tracking down and fixing a race condition by deferring a function call:
Using lambda functions to handle irregular cases of code execution:
Making ball hittable after going back on table, and forcing turn change on foul:
Devising simple and flexible way to keep track of balls remaining per player:
Setting up win condition by checking eight ball potting and balls remaining:
Handling game ended without bloating game state, and displaying result:
Fix bugs and wrap up game ran out of characters for timestamps:
Thank you!:
Taught by
Tutemic