Problem with Runner Tutorial on Defold 2 editor

Hi, I’m following the runner tutorial on the defold homepage and I follow everything up to STEP 6 - Ground physics and platforms.

When I do everything up to substep 7, and get to the part where it says

Now you should be able to try running the game (Project ▸ Build and Launch). The frog should run on the ground and it should be possible to jump with the kbd:[Space] button. If you run the game on a mobile device, you can jump by tapping on the screen.

The frog runs, it is affected by gravity, but whatever I do I cannot get it to jump.

I have the game input bindings as required and the frog does have focus, but the jump function is never actually called…

Check in the script attached to the frog. In the init function there should be a call to acquire input focus:

msg.post(".", "acquire_input_focus")

Double check that this line of code is there and that there are no spelling mistakes.

Next thing to check is if any input reaches the on_input() function of the same script. Either set a breakpoint in on_input() and run the debugger or add a print(action_id) as the first line of the function. Is the function called?

Do you see any errors in the console by the way?

No console errors.
The frog has acquired focus, since when I call the function again I do get a warning saying that “level/hero” already has acquired focus.

here’s my frog’s code:

-- gravity pulling the player down in pixel units/sˆ2
local gravity = -20

-- take-off speed when jumping in pixel units/s
local jump_takeoff_speed = 900

function init(self)
	-- this tells the engine to send input to on_input() in this script
	msg.post(".", "acquire_input_focus")

	-- save the starting position
	self.position = go.get_position()

	-- keep track of movement vector and if there is ground contact
	self.velocity = vmath.vector3(0, 0, 0)
	self.ground_contact = false
end

function final(self)
	-- Return input focus when the object is deleted
	msg.post(".", "release_input_focus")
end

function update(self, dt)
	local gravity = vmath.vector3(0, gravity, 0)

	if not self.ground_contact then
		-- Apply gravity if there's no ground contact
		self.velocity = self.velocity + gravity
	end

	-- apply velocity to the player character
	go.set_position(go.get_position() + self.velocity * dt)

	-- reset volatile state
	self.correction = vmath.vector3()
	self.ground_contact = false
end

local function handle_geometry_contact(self, normal, distance)
	-- project the correction vector onto the contact normal
	-- (the correction vector is the 0-vector for the first contact point)
	local proj = vmath.dot(self.correction, normal)
	-- calculate the compensation we need to make for this contact point
	local comp = (distance - proj) * normal
	-- add it to the correction vector
	self.correction = self.correction + comp
	-- apply the compensation to the player character
	go.set_position(go.get_position() + comp)
	-- check if the normal points enough up to consider the player standing on the ground
	-- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
	if normal.y > 0.7 then
		self.ground_contact = true
	end
	-- project the velocity onto the normal
	proj = vmath.dot(self.velocity, normal)
	-- if the projection is negative, it means that some of the velocity points towards the contact point
	if proj < 0 then
		-- remove that component in that case
		self.velocity = self.velocity - proj * normal
	end
end

function on_message(self, message_id, message, sender)
	if message_id == hash("contact_point_response") then
		-- check if we received a contact point message. One message for each contact point
		if message.group == hash("geometry") then
			handle_geometry_contact(self, message.normal, message.distance)
		end
	end
end

local function jump(self)

	msg.post("hero#script", "acquire_input_focus")
	-- only allow jump from ground
	if self.ground_contact then
		-- set take-off speed
		self.velocity.y = jump_takeoff_speed
	end
end

local function abort_jump(self)
	-- cut the jump short if we are still going up
	if self.velocity.y > 0 then
		-- scale down the upwards speed
		self.velocity.y = self.velocity.y * 0.5
	end
end

function on_input(self, action_id, action)
	if action_id == hash("jump") or action_id == hash("touch") then
		if action.pressed then
			jump(self)
		elseif action.released then
			abort_jump(self)
		end
	end
end

you can see the frog acquires focus during init().

using print(action_id) as the first line of on_input(), gives me:

DEBUG:SCRIPT: Script: 0x16770fa0	nil	table: 0x16773d80

so that nil over there makes me suggest that there is no actual action being called out since hash(nil) != hash(“jump”)…

I just don’t know what’s missing or why…

finally, here’s my game.input_binding

key_trigger {
  input: KEY_SPACE
  action: "jump"
}
mouse_trigger {
  input: MOUSE_BUTTON_LEFT
  action: "jump"
}
touch_trigger {
  input: TOUCH_MULTI
  action: "jump"
}

I’m at a loss of what could be missing or wrong :confused:

Uh-oh, after watching closely I see that the on_input function is only being called for MOUSE MOVEMENT but not for any keys that I press, and that puzzles me further :confused:

Edit: After removing all other triggers from game.input_binding, it works… but I don’t understand why it doesn’t work when I add more than one binding.

I’d like to be able to make our froggie jump by either hitting spacebar or left-clicking or touch, why wouldn’t it work?

You should not have a binding for touch. That’s for detecting multi touch. A binding for left mouse button will also work for single touch.

You’ve actually hit a bug. See Can input actions in defold not have the same name? (DEF-1855)

I see, is that behaviour documented? I was just trying out the tutorial as an introduction yesterday.

Alright, I hope it gets sorted out soon, luckily my aim is currently to develop for PC using defold.

Thanks for your help!

Just to avoid any confusion:

  • Single touch works on mobile by having a mouse trigger binding for left mouse button or mouse button 1.
  • Multi touch works on mobile by having a touch trigger binding
  • Having both a multi touch and mouse trigger with the same action causes touch to not work as expected.