• Godot Help
  • How would I add a cheat code to a title screen

Raptorkillz func _input(e):
for a in InputMap.get_actions().filter(func(aa): return e.is_action_pressed(aa)).slice(0,1):
s += a if not s else " " + a
for k in cheats.keys(): if s.contains(k): code_entered.emit(cheats[k]); s = ""

is this function even correct?

im not fond of lambdas because its convoluted.

i dont like this line:

s += a if not s else " " + a

Seems like if s - the entered cheat sequence is nothing/empty then you start new sequence with " " a space at the beninging. So it will never match the cheat or i maybe wrong here?

also the last line

for k in cheats.keys(): if s.contains(k): code_entered.emit(cheats[k]); s = ""

does ; at the end or signal.emit() means if condition fails then do - s = ""??

  • xyz replied to this.

    kuligs2 is this function even correct?

    It is. I wrote it. In a compacted tabletdev style 😉

      xyz If you wanted to know I was debugging the outcome by adding a label that said cheat successfully entered when the cheat was successful but the text didn't output anything

      • xyz replied to this.

        Raptorkillz Use a trivial test example.

        • use actions you know 100% are defined and map 1:1 to physical input, because you might have messed up something with your action definitions
        • use trivial sequence to speed up your testing, because you're testing how the parts of your code are communicating so the actual sequence is not important
        • print immediately at the start of the signal handler
        • print the sequence as it builds up
        • double check your signal connections
        • be sure to catch and understand all error messages the engine might be reporting
        • If you can't use print() on your dev platform - use a different platform or set things up in a way so you can see your prints. Developing without printing is not a very wise thing to do. It just makes tracking the flow of your code needlessly more difficult.
        class_name CheatCodeCapture extends Node
        signal cheat_code_entered(name: String)
        var s: String
        var cheats: Dictionary = {"ui_left ui_right" : "cheat1"}
        
        func _input(e):
        	for a in InputMap.get_actions().filter(func(aa): return e.is_action_pressed(aa)).slice(0,1):
        		s += a if not s else " " + a 
        		print("current sequence: ", s) # debug
        		for k in cheats.keys(): if s.contains(k): cheat_code_entered.emit(cheats[k]); s = ""
        
        func _ready():
        	cheat_code_entered.connect(on_cheat)
        	
        func on_cheat(name):
        	print(name) # debug

          kuligs2 Here's an "educational" version for easier understanding:

          class_name CheatCodeCapture extends Node
          signal cheat_code_entered(name: String)
          var action_sequence: String
          var cheatcodes: Dictionary = {"ui_left ui_right" : "cheat1"}
          
          func _input(event):
          	# iterate through actions defined in input map
          	for action in InputMap.get_actions():
          		if event.is_action_pressed(action):
          			# accumulate actions
          			if not action_sequence.is_empty():
          				action_sequence += " " # insert space between actions
          			action_sequence += action
          			# check if the current action sequence is present in any of cheatcodes
          			for code in cheatcodes.keys():
          				if action_sequence.contains(code):
          					# action sequence found, emit the signal and clear the accumulated sequence
          					cheat_code_entered.emit(cheatcodes[code])
          					action_sequence = ""
          			break

          xyz But now how would I make it work with the sonic 3 level select cheat

          
          {"gm_up gm_up gm_down gm_down gm_up gm_up gm_up gm_up" : "sonic 3 level select"}
          • xyz replied to this.

            Raptorkillz Well, just add that sequence to the dictionary. But as I said you need to check that your actions are properly set up. To which input events do you have those gm_* actions mapped?

              xyz Okay and they are named correctly

              here's the input maps

               [["gm_left","gm_right"],["gm_up","gm_down"],"gm_action","gm_action2","gm_action3","gm_super","gm_pause"]
              • xyz replied to this.

                Raptorkillz Those are just action names. This doesn't show to what input events they are mapped.

                  xyz Okay This inputs gm_left","gm_right moves the character left or right And this inputs allows the character to crouch and look up "gm_up","gm_down" And this inputs allow the character to jump "gm_action","gm_action2","gm_action3" This Input turns sonic to super sonic gm_super and this input pause/starts the game "gm_pause"

                  • xyz replied to this.

                    Raptorkillz Yes but they need to be mapped to some physical input events in order to work. Can you show a screenshot of your input map tab in the projects settings?

                      Raptorkillz As I said the built in actions may be "overriding" your defined actions if both are mapped to same input events. What gets printed as "current sequence" when you press left/righ/up/down actions?

                      You can try with this input function instead. It prioritizes last added actions:

                      func _input(e):
                      	var actions = InputMap.get_actions().filter(func(aa): return e.is_action_pressed(aa))
                      	if actions:
                      		var a = actions[-1]
                      		s += a if not s else " " + a
                      		print("current sequence: ", s)
                      		for k in cheats.keys(): if s.contains(k): cheat_code_entered.emit(cheats[k]); s = ""