3

I'm stuck with generating debug output for my game objects using Haskell/Yampa (=Arrows) (with HOOD).

My engine basically runs a list of game objects which produce Output states (line, circle) which are then rendered.

data Output = Circle Position2 Double | Line Vector2

output :: [Output] -> IO ()
output oos = mapM render oos

render :: Output -> IO ()
render (Circle p r) = drawCircle p r
render (Line   vec) = drawLine (Point2 0 0) vec

The player object just moves to the right and is represented as a (positioned) circle.

playerObject :: SF () Output -- SF is an Arrow run by time
   p <- mover (Point2 0 0) -< (Vector2 10 0)
   returnA -< (Circle p 2.0)

mover is just a simple integrator (acceleration->velocity->position) where I want to observe the velocity and render it as debug output as an (unpositioned) Line.

mover :: Position2 -> SF Vector2 Position2
mover position0 = proc acceleration -> do
    velocity <- integral -< acceleration -- !! I want to observe velocity
    position <- (position0 .+^) ^<< integral -< velocity
    returnA -< position

How can I create additional graphical debug output for internal values of my game object functions?

What actually should happen is in output, first render the actual object (circle) but also render additional debug output (movement vector as line). Probably I can achieve this with HOOD but I'm still not fluent in Haskell and don't know how do adopt the HOOD tutorial for my case.

Edward Z. Yang
  • 26,325
  • 16
  • 80
  • 110
Gerold Meisinger
  • 4,500
  • 5
  • 26
  • 33

2 Answers2

2

I don't know HOOD but Debug.Trace is easy:

> import Debug.Trace
> mover position0 = proc acceleration -> do
> > velocity <- integral -< acceleration
> > position <- trace ("vel:" ++ show velocity ++ "\n") $
> > > > > > > > > > > (position0 .+^) ^<< integral -< velocity
> > returnA -< position

Note that it shouldn't be put on the line defining velocity.

sauf
  • 182
  • 1
  • 4
  • This doesn't give graphical output, though, just text on the console, and is a bit limited in general. Sometimes `unsafePerformPrintfDebugging` is all you really need, but I think the questioner here is after more than that. – C. A. McCann Jul 15 '10 at 13:50
1

What you probably want to do is make mover more flexible, to support adding out-of-band debug information (the value of velocity) to be rendered. I don't think HOOD is relevant for your problem, since you already have the FRP framework for handling continuously changing values. Just arrange for velocity to be output.

Something like:

mover :: Position2 -> SF Vector2 (Position2, Vector2)
mover position0 = proc acceleration -> do
    velocity <- integral -< acceleration -- !! I want to observe velocity
    position <- (position0 .+^) ^<< integral -< velocity
    returnA -< (position, velocity)

playerObject :: SF () [Output]
   (p, v) <- mover (Point2 0 0) -< (Vector2 10 0)
   returnA -< [Circle p 2.0, Line v]
Edward Z. Yang
  • 26,325
  • 16
  • 80
  • 110
  • 1
    Changing and breaking the interface is exactly what I want to avoid. The signature of the function should stay the same, but some extra annotations between dataflows in the function body, which are communicated to an external system and presented in a visual style. Like GHood but with interactive program capapbilities. – Gerold Meisinger Jul 03 '11 at 09:42
  • If you don't mind recomputation (unfortunately, Yampa in principle should be able to avoid this, but doesn't), you can factor out veloctiy calculation to its own identifier, and then access that from the top level. Or you could do some unsafe action at a distance to propagate the relevant bits to the top level. – Edward Z. Yang Jul 03 '11 at 15:58