Rubber ducky debugging

I was going to ask a question, but in typing the question out I figured out the answer. One of the people I know called this ‘rubber ducky debugging.’
I suggest you all do it.

When you’re stuck and don’t have a clue
Just sit a moment or two
Then write out your problem
And then 'cause you’re awesome
The place you were stuck will be through

And that didn’t quite rhyme did it?

Anyway, I’ll use polling instead of callbacks. Many things will get easier.

What’s the difference between the two?(And no, I don’t know what they are for… >.<)

Polling:
Every frame check to see if a condition is met

Callbacks:
When the condition is met, run the intended function

eg:
A keyboard sensor set to a specific key running a motion actuator is a ‘callback’
A python script running from an always sensor checking a keypress is ‘polling’

Now I can hear you say: why bother with the python script. (or why bother with polling, it’s more processor intensive’)
It’s easier in certain circumstances, such as when you don’t always want the thing run. Then you have to have your intended function check to see if some unrelated condition is true. And then your code becomes unreadable.

If the thing interacts with another thing, its possible to check things about the other object,
Etc, sometimes I divide control with many objects… Comments help, but the code speaks for itself.

This is below object level BPR, the code is infact as unnattached from any object as it is possible for it to be.

So this is an input system. It can load and save a keymap/axis map (it works with keys, buttons, mouse), and has some internal representation of the key/action states.
But the rest of the game needs to be able to access this action state. It could be done by:

  • at game start, passing the input function a lot of function names + parameters, which the input script executes
  • whenever another script wants the state of an action, it goes and asks the input script (by calling a function)

Now, both work, but lets say the player is in a car, and we need to check the amount of petrol/gas in the car before we can move. With the first system, th callback has to know about the cars internal state. If it weren’t a car but were a spaceship, and every movement had to check the fuel, then every movement function also has to have know about the spaceship. This amouts to a lot of interconnection between the code, and if I want to change something it can be quite unwieldy.
If you use polling, then you can have a single check for the fuel level as part of the spaceships own code. This is much more readable.

It’s also much easier to debug. If my spaceship suddenly starts drifting by itself, polling enables me to immediately eliminate the input module as the source of the bug just by printing the state of the action. But for the callbacks it’s hard to know when/exactly why the callbacks were executed.

I see,

What about callbacks, with polling if a bool is true?

So your debugger is only running if you turn it on?

Maybe have a player debugger, vehicle system debugger etc.
To keep the debug list short,

Your question makes no sense. Objects have no such thing as a debugger.

@sdfgeoff

I found this an intuitive concept for input handling. I wouldn’t go to the same level of depth as outlined in the system just yet, but it will be useful for any future development.

In short, it features event “contexts” which describe a situation within which events are available. Instead of having an active entity (Vehicle/Player) which polls events from the input layer, the input manager will select the active event context and push events through a callback. I thought this quite effective.

Your example is slightly missing the point of callbacks. The idea is that the movement code resides on the spaceship/player and that particular object will have its own callbacks to register to the input manager. Whenever you switch between the two, the disabled object unsubscribes from the input manager. Similar, but not exactly so, to the article’s method.

You can also poll state directly. To be honest, it depends upon your design preference. But, I would advise the following:

  1. Separate the input polling from the BGE. That way, you could for example performing game replays by simply providing recorded inputs to the game instead of player inputs. You can still use a global singleton class for this, though most recommend against it, instead it is better to provide the input state whenever you update the gamestate.

I.E


for entity in entities:
    entity.handle_input(input_state)

However, given that in many games, there will also be NPC characters and other entities which do not handle input from the player, it would be cumbersome to have to write a separate update loop, and foolish to provide useless state by the same method as players.

In the interests of code-reuse, I prefer the UDK method which encourages the use of player “controller” which handles the interface between the actuator (player) and the sensor (inputs) to allow either players or NPCs to control the same player object “Pawn”.

So, instead I prefer the callback-based approach.

I originally wrote a small code sample, then implemented a dummy system.

Press E to disable the player (by setting the context active state to False), WSAD to move around.
Notice that the controller just handles inputs. The entity itself would be a class with its own additional functionality (i.e shoot_weapon) that builds upon the KX_GameObject features.

scene.blend (559 KB)

Right now I use a action map

Based on other properties, you could change the targets of the action map, and use common conventions, like sending the other script the action map.

Like

Move=[]
for sensor in own['SensorList']: 
    if sensor.positive:
        Move+=[sensor.name] 

Then you can just send the move data to the car, or player, or ?

Maybe set a property with it,
And run

If string!=“EMPTY”-----------run car input script

You could then use

If SensorName in Move:
Or
If Move=[‘Sensor1’,'Sensor2]:

@bpr
You’re not thinking grand enough yet. I have a challenge:

Create a script (or logic setup) that has the following features:

  • Takes all input (keyboard mouse joystick)
  • Customisable mapping
  • And returns in some other-script accessible way ‘action’ = percent.
    Example output:
    Xmotion = 0.5
    weapon1 = 0

Write up full documentation for it, then tell us about it when it’s done. Not when you’re working on it. Only when it’s done.

@agoose
The way I read that article is simply that it suggests implementing a system for managing different callbacks. (or contexts).
I see your point with callbacks, but here’s the thing:

  • Proportional Control

Callbacks for button-based-simple control is easy. Call the function when the event is active (ie click mouse -> shoot gun). On = called, Off = not called
But let’s say I’m controlling a space-ship. Regardless of if the input is button or axis (that should be handled by the input system sensibly), you’re going to have to call your callback every frame because zero deflection is a valid proportional state.
Definitely doable, simply pass the proportion into the callback as a parameter, but to me it doesn’t fit with the concept of On = called, Off = not called that callbacks tend to do.
My current design treats everything the same. Nothing is a button. All input varies from -1 to 1, thus every callback will be called every frame.

I think you’ve convinced me to try the callback method though. I’ll extend my manager to handle both. It’s only a couple lines more code.

The article does two things. Firstly it introduced the idea of an event context, which will be useful later on, such as for dispatching to specific objects as I demonstrated, and also the notion of a callback entry point. The context allows us to simply deny input to a listener without it having to necessarily realise / effect this, such as when the UI is overlayed or a game over screen is showing. The callback as entry point is mainly a delivery method. There are other means, but for me I consider it especially important to separate the inputs from their effectors. The blend file shows an example of this.
How this inputs are interpreted should arguably be handled by another aspect of the class, that may well (as I did) poll a variable. You inevitably have to poll, and it isn’t sensible to have callbacks per event, instead per context.

What is this thread about?

Is it about the concept of: looking at a problem from another perspective, or
polling vs. event processing?

I’m a bit confused.

Btw. I never heard about rubber dug debugging. Nevertheless I experienced this effect quite a lot in my lifetime. The secret is simply you look at the issue from another perspective. You can do that by making a break (and forget the intermediate results) or by slowing down (and see the other crossroads you missed before). You do not need to talk to a rubber dug. Often you simply talk to someone else. This person might ask for some clarification on this or that … which lets you see an alternative path. So it is a sort of distraction.

In our case you can simply write down your issue in a thread. While you formulate your issue, you get the other perspective. Reviewing a problem gives other alternatives even to already working aspects. You still need to decide if the alternative is better than what you already have … at least now you have a choice ;).

SdFGeoff, my current system could do that, and it’s built already, it’s running my protagonist rig in the New Wrectified Rebooted demo,

In the filter


if move =['Forward']:
   YourValue1=.5
   YourValue2 =.25

Etc,

You could also use filters so holding w adds to the value to a max value,


if Move='Forward','Space']
   if value&lt;=.9:
        value+=.1

About custom key mapping,
Just have a script that edits the keyboard sensors?
I am not sure, but can you create a sensor in game?

@bpr

you don’t need a sensor for input, you can just use the bge.events
here is an example from the api


<i># The all keys thing without a keyboard sensor (but you will</i>
<i># need an always sensor with pulse mode on)</i>
<b>import</b> <b>bge</b>

<i># Just shortening names here</i>
keyboard = bge.logic.keyboard
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED

<b>if</b> keyboard.events[bge.events.WKEY] == JUST_ACTIVATED:
        <b>print</b>("Activate Forward!")
<b>if</b> keyboard.events[bge.events.SKEY] == JUST_ACTIVATED:
        <b>print</b>("Activate Backward!")
<b>if</b> keyboard.events[bge.events.AKEY] == JUST_ACTIVATED:
        <b>print</b>("Activate Left!")
<b>if</b> keyboard.events[bge.events.DKEY] == JUST_ACTIVATED:
        <b>print</b>("Activate Right!")

http://www.blender.org/api/blender_python_api_2_70_5/bge.events.html

this also registers the joystick input(controller) so you can also implement controller support if you want.

You don’t need bge.events. You can just use sensors. It comes with a nice gui and allows mapping of input by naming the purpose. This allows joystick sensors too.

However Monster, most people expect a reasonably modern game to have user-configurable buttons. For instance, I play with Space as move forwards, Left shift as backwards. S for left, F for right. (In some games, E and D for up/down or jump/crouch). I have never found a game with those as default, nor such an optimized keyboard configuration (optimized for comfort, it allows my hand to be in a rest post)

I was about to release the input system made based on this discussion, but have hit a snag: Joysticks.
I don’t have one to test with. So far it handles mouse and keyboard perfectly, but I want to add joystick. Time to hunt down one of my friends… Or maybe release it without joystick support

As for the purpose of this thread: There wasn’t one until leanardoe asked a question.

As far as I can see, the BGE uses polling already in the form of .events.
I just have to check if a particular key is in the active keys list.

In my own case, since I’m using a Finite state machine each state polls for certain events every tic as a state owned function. I can have a different controls fuction for each state or a more general function such as on_ground_controls().

If I’m not using states I would need some kind of event manager to check if the agent is valid for a specific kind of input.

User configurable input?

I developed such a system quite some time ago. It became a bit too complicated in the end.

Finally I realized, I can simply dig through all the keyboard/mouse/joystick sensors, and reconfigure them as I like. Just some simple Python code can do that. The only downside is that you can’t replace a keyboard button with a mouse button. [Most games do not allow that anyway => no problem on that.]

What is left is the not so simple to build GUI to allow the user reconfiguration. This is something you need to create regardless what system you implement.

One problem on that is - the BGE does not support OS keyboard mapping. So you are limited to display key-codes and the not really sufficient default mapping to US keyboards (which btw. are not used in Germany at all). This means you see incorrect characters representing keys in the GUI.

Polling and event handling are contradictory

Either you poll or you get noticed by an event.

There might be polling behind event creation but this is not visible. The advantage of events is that business code runs only when needed. The other advantage is that events can fall out of normal processing anyway.

E.g. the Physics Engine has to calculate collisions all time. There is very low performance impact on generating the events. The information is already there. This is the reason why collision sensors have not that much impact.

The opposite example is a ray, near and radar sensor … this information does not fall out of the usual Physics Engine processing. Therefore the are polled as long as the sensor stays active. But the business process (your game logic) does not need to care.

A finite state machine represents an event system too. The transitions are triggered by event. You just need to check the transitions if at least one event might happen. If you already know there is no change … no need to check.

I guess your designed your finite state machine in a way that you need to check the events all the time. This might be necessary … may be not. Usually finite state machines do not need to run all the time. This is what makes them so efficient.

I would need to setup a callback, or poll that way, with my system the python is only triggered when keys are pressed, Agoose made a good example of callbacks, but they are just too functionified for me, as I dont really use functions very often.