I’m lazy following tutorials and when I was told Godot64 has a Game Jam with an abundance of source code projects uploaded on Github I decided to start figuring out how these games by diving straight into the code.
NOTE: It helps to have a good understanding of Python to understand GDScript. If you don’t then try to follow along because it’s just english anyway. Ok here we go lets start coding.
Finding input controls:
Lets not waste any time.
First step, understanding that every application starts with Main.gd. So I grab the code here → https://github.com/CowThing/MouseBoat/blob/master/scripts/main.gd
Line 16 is our default function. Not a constructor, just where initialization begins.
func _ready(): randomize() set_process_input(true) AudioServer.set_stream_global_volume_scale(0.5) load_fish() get_node("Main Menu").popup() get_node("Main Menu Camera").make_current()
Every input control is initialized with set_process_input(true).
Scrolling further down are a bunch of functions used for initialization and loading models, sound files, UI stuff etc.
Now I reach line 27:
func game_start(): player.set_state(player.STATE_MOVE) player.get_node("Camera Pivot/Camera").make_current()
Ok this looks relevant. I don’t know what player is so I do a quick search in the same script and i return to the top of the file to find this at line 13:
onready var player = get_node("Objects/Player")
get_node(…) looks through your hierarchy in the Godot editor shown below
Under our the Objects node is a child node Player. Hitting F key in the 3D scene in our editor focuses into our player character.
Perfect. Now, we know how the player character is loaded but how do we find out which script it’s using?
Look in your inspector on the right of the editor to find under Script:
We know now that Boat.gd is the script it uses for controls. Opening this file and we see that a constant was defined at line 10 for our get_node previously:
const STATE_MOVE = 0
Searching further into our code on where STATE_MOVE is defined we reach line 79:
if current_state == STATE_MOVE: if moveF: var d = get_transform().basis.z lv += d * movespeed * step elif moveB: if lvlen <= movespeed * 0.2: var d = -get_transform().basis.z lv += d * movespeed * 0.2 * step if lvlen >= movespeed * 0.2: lv = lv.normalized() * movespeed * 0.2 if moveL: av.y += step if moveR: av.y -= step av.y = clamp(av.y, -turnspeed, turnspeed) if lvlen >= movespeed: lv = lv.normalized() * movespeed if lvlen > 2: if get_node("RippleSpawn").get_time_left() <= 0: get_node("RippleSpawn").set_wait_time( 0.3 + ((movespeed - lvlen) / movespeed) * 0.7) get_node("RippleSpawn").start() else: get_node("RippleSpawn").stop() else: get_node("RippleSpawn").stop() lv -= lv * 0.9 * step av -= av * 0.9 * step
Bingo, We have the control functions in the bag.
The real fun now is to change this part of the code to our liking (if needed at all).