Home > MHEG > MHEG+ Game Development Tutorial, Part #1 — Timing

MHEG+ Game Development Tutorial, Part #1 — Timing

November 26, 2008 Leave a comment Go to comments

Introduction to this Series

One of the joys of my job at the BBC is staying back after hours and trying to nut out how best to write real-time games on current interactive television platforms.  That is, trying to write the kind of games that you might have once played in an arcade, or maybe on your BBC Micro, but allowing you to play them via the ‘Red Button’.  See this post for a video of some of my efforts so far.

Here in these tutorials I hope to share with you some of my findings in trying to get the best out of the MHEG platform.  I also hope to demonstrate the power of the MHEG+ programming language, an extension to MHEG.  MHEG+ has been developed in-house at the BBC and compiles down to traditional MHEG/ASN, but is a far richer langauge than its predecessor.

For these tutorials I will assume you have some background in programming generally and hopefully some experience writing MHEG or interactive TV applications (MHP, OpenTV, etc.).  The code samples will all be in MHEG+ which at time of writing is not available outside the BBC, however efforts are being made to attempt to open source MHEG+ development tools, so watch this space…

I guess for the time being then you most likely won’t be able to compile or run these applications, but hopefully one day soon you will be able to.  Therefore I suppose the code herein is currently just for educational purposes, but then that is the point of the series :-)

So, without further ado…

Part #1: Timing

The first significant challenge that I came across when writing MHEG games was that of timing.  How could I ensure my game would run at virtually the same speed on any set top box?

Unlike more sophisticated languages (yes, I openly admit that MHEG is not the most sophisticated language, but then it was never designed to be) MHEG does not provide the developer with a means of retrieving accurate clock information.  The most fine-grained time information you can retrieve (achieved by a call to the GetCurrentDate resident program) provides no better than whole second precision.

MHEG Timers however provides us with some hope.  The :SetTimer action expects a millisecond count as an argument – hooray! we have precision timing.  Well, almost.

The UK MHEG profile goes into considerable detail about the accuracy of Timers which I won’t go into here except to say that they are accurate enough for most gaming needs.

The UK profile also states that the MHEG engine must start a timer immediately when a call to :SetTimer is encountered.  This we can use to our advantage.

Let’s try this out in some code, here is a simple MHEG scene with a timer. It is written in MHEG+:

{:Scene ("/tut/tut1.mhg" 0)
 :Items (
        // Constant declarations
        // ---------------------
        {:IntegerConst constTimerDelay :ConstValue 100}

        // Variables -----------
        // ---------------------
        {:IntegerVar intCount :OrigValue 0}
        {:OStringVar strTemp :OrigValue ''}

        // Ingredients ---------
        // ---------------------
        {:Text txtText
         :OrigContent           '0'
         :OrigPosition          0 [(576 - 100) / 2]
         :OrigBoxSize           720 100
         :HJustification        centre
         :VJustification        centre
        }

        {:Timer tmrTimer}

        // Links ---------------
        // ---------------------
        {:Link lnkStartup
         :EventSource           0
         :EventType             IsRunning
         :LinkEffect
         (
                :SetTimer(0 tmrTimer constTimerDelay)
         )
        }

        {:Link lnkGameTick
         :EventSource           0
         :EventType             TimerFired
         :EventData             tmrTimer
         :LinkEffect
         (
                :SetTimer(0 tmrTimer constTimerDelay)

                intCount.Add(1)
                strTemp.SetVariable(:IndirectRef intCount)
                txtText.SetData(:IndirectRef strTemp)
         )
        }

        {:Link lnkKeyText
         :EventSource           0
         :EventType             UserInput
         :EventData             KeyText
         :LinkEffect    ( :Quit() )
        }
 )

 :InputEventReg 4
 :SceneCS 720 576
}

The key elements of the scene are its :Links. Links are where most processing happens in MHEG applications. MHEG links could have been called “action listeners”. You write links to listen for particular events, when this event occours your procedural code in the :LinkEffect section is executed by the MHEG engine.

The links defined in the scene are:-

  • lnkGameTick — this link is fired whenever the timer times out.  Its effect is to increment our integer counter variable, convert it to a string (storing in strTemp) and update the display (txtText).  The very first thing we do in the link effect however is set the next timer event.
  • lnkStartup — this link is called after our scene has finished loading.  It is important because this is where we set up the first timer event.  Timers cannot be set to fire automatically when the scene loads.
  • lnkKeyText — this link listens for a key press, specifically the Text button on your remote control.  Its effect is to simply exit the application (it calls :Quit).

Other things of note in the code:-

  • MHEG+ allows us to use names for our objects, conversely classic MHEG requires that all objects be identified solely by a number.
  • The actions in lnkGameTick are using MHEG+ dot notation (object dot action).
  • The vertical position of the txtText Text object is written as an expression ([(576 - 100) / 2]), this is an MHEG+ feature, the expression is evaluated at compile time.
  • We declare a constant (constTimerDelay) another MHEG+-only feature.
  • :InputEventReg and :SceneCS at the bottom of the scene if you are wondering are indeed required. Let’s not go into detail about these now though as they can be considered just boilerplate code in most cases.

If you haven’t guessed by now, when its run the scene displays a counting number in the centre of the screen, which updates every 100ms.  Here is a cropped screenshot of the app after letting it run for approximately [100 * 103] milliseconds:-
tut1

The key lesson to take from this is that we set the timer at the top of lnkGameTick. Why?  By doing so we are ensuring that the timer event will be fired at the most consistent rate possible in MHEG.  The timer can only ever be late. We simply now have to make sure that our game loop is efficient enough to be executed within our specified time period (here, 100ms).

So that’s it for part #1 of my MHEG+ tutorial.  I hope that you got something out of it.  I would imagine the most useful content here was the code section — is this the first time you have seen MHEG+ code?

I hope later posts in the series will look into some of the more advanced features of MHEG+ such as If statements, For loops and Macros, plus I shall of course endeavour to include the complete source code for a number of simple, but playable, games.

Ciao for now. Hope to be back soon.

Resources

Other posts in this series:
Part #2 — Animation

About these ads
  1. Derek
    December 9, 2008 at 6:01 am | #1

    Good work, looking forward to see the “For loops” and “Marcros”.
    Where can I get the MHEG5+ complier?

    And do I have to Deactivate the lnkStartup like

    {:Link lnkStartup
    :EventSource 0
    :EventType IsRunning
    :LinkEffect
    (
    :Deactivate lnkStartup
    :SetTimer(0 tmrTimer constTimerDelay)
    )
    }

    ? it only sets the Timer once or whenever the application is running?

  2. purple floyd
    December 9, 2008 at 10:49 am | #2

    Hi Derek, thanks I appreciate your feedback.

    The MHEG+ compiler was written in house at the BBC, it may (or may not) be made public some time soon. I’ll be sure to blog about it if it does!

    With regards to deactivating lnkStartup, true it is very common to code a link that Deactivates itself as its first action, however, in this case is not necessary. From the MHEG-5 spec:

    IsRunning – This event is generated when the RunningStatus attribute changes from False to True

    Therefore our scene (object #0) will only generate an IsRunning event when it loads and at no point after this while it remains running.

    I’m working on part #2 of this series so stay tuned…

  3. Julian Smith
    February 27, 2009 at 8:56 am | #3

    Is there any update on whether the MHEG+ compiler is going to be available (or not).
    Can’t wait to use it.
    Thanks

  4. purple floyd
    February 27, 2009 at 10:36 am | #4

    Hi Julian. No news as yet I’m afraid. When/if it is released it’ll be announced here and very likely on the BBCi Labs blog and BBC Backstage blog. Sorry can’t offer more info than that. Good to hear from a fellow MHEG engineer. Cheers

  5. surawut
    October 30, 2009 at 2:46 am | #5

    Dear PurpleFloyd
    I’m so interested what you are doing. Now, I’m studying on MHEG-5 development for digital television. what I found is that it is very hard to find MHEG-5 development tool. I can’t even find any working ASN.1(DER) encoder for MHEG-5 application. The only way I can think how to get it work is to develop MHEG notation then encode it to ASN.1(DER). After that I will need to corporate the MHEG appliccation to DSM-CC to be ready for MPEG-2 transportstream in order to see the program result on digital TV screen. I’m trying just to get my Helloword program working but no luck or enough effort I can’t get it work. If possible could you point the better way for me. It would help me a lot.

    I would like to be like you who can enjoy yourself with what you are doing.

    Best regards,
    Eddy

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: