Gamasutra.com Features - Reflections on Building Three Scripting Languages
It's free to join Gamasutra!|Have a question? Want to know who runs this site? Here you go.|Targeting the game development market with your product or service? Get info on advertising here.||For altering your contact information or changing email subscription preferences.
Registered members can log in here.Back to the home page.

Search articles, jobs, buyers guide, and more.

Gamasutra
April 12, 2007

Reflections on Building Three Scripting Languages

arrowrightPage One
arrowrightPage Two
arrowrightPage Three
arrowrightPage Four
arrowrightPage Five

Printer Friendly Version




Latest Letters to the Editor:
Perpetual Layoffs by Alexander Brandon [09.21.2007]

Casual friendliness in MMO's by Colby Poulson [09.20.2007]

Scrum deals and 'What is Scrum?' by Tom Plunket [08.29.2007]


[Submit Letter]

[View All...]
  


Reflections on Building Three Scripting Languages


Language 3: FLIRT

LimeLife didn’t know it at the time, but they needed a technology to manage their application porting and they readily accepted it when offered. Writing code in J2ME (Java) and then recoding it in Brew (C ) is tedious and the multiple screen sizes of phones make generating code for each screen size effortful. An API doesn’t work so well when your code needs to be in two different languages.

Build, buy, or API? Some mobile application companies have written standardized UI generators and some have written things like a scripting language that rehosts Java just so they can download their code as data at runtime. The primary commercial candidate for the J2ME/Brew network portable language was the UIEvolution system. But it was expensive, only handled scripting (not layout), and generated code similar in size to Java itself. I thought we could do much better, hence I built FLIRT.

FLIRT is not just a scripting language repackaging java/brew code into a one-to-one-correspondence. FLIRT integrates scripting and display in a language designed specifically for cell-phones. Size is the paramount concern. While Java is designed to produce highly compact code, FLIRT script saves 50% over Java code. Java tries to be a universal language across machines big and small. But cell phones imply significant limitations and a well-designed scripting language can take advantage of that.

Since a major “reusable” component of mobile applications is code to manage the UI, I organized FLIRT around a state description of each screen. The state describes what softkeys are to be used, what script code to execute in response to incoming events, and what graphical elements to draw on the screen in what order.

The first design decision I made was to restrict the range of all script arguments to one byte, using indirection as needed to access tables of things taking more than a byte (e.g., 32-bit integers, colors, fonts, strings, graphics).

The second design decision was to eliminate local variables. All user data is normally kept in global two-dimensional arrays, one for bytes, 32-bit integers, strings, and graphics. The [0][] is for transient unrelated values, while other first dimensions hold sets of related information. For example all the strings of a menu would be in, for example, strings[3][]. So a script element defining a menu could refer to that using the single byte value 3. Of course the language allowed you to automatically label dimensions so you never used the number.

For example, defining your global strings array might look like this:

This would define stringSets[0] to be anonymously labeled but its members have labels (labels are named followed by colon) and sometimes initial values. StringSets[1] is called sTRENDS_MENU and is a list of anonymously named strings which would be the names of menu choices.

The user script will have named intial values for the data arrays, as well as arrays describing fonts, colors, and softkeys. All of which can then be accessed using a single byte value (name) used in the appropriate instruction or element context.

For example, a TextRect display element can be thought of as a subroutine call to display a set of text somewhere on the screen. It’s actually more than that, because it is not code but data to be interpreted, and the data can be modified by the scripting language. This means the script can scroll the content, move it around, change what text it points to, etc. Be that as it may, this call takes 15 arguments to completely define the element. Since each argument is always a byte, it means it takes 15 bytes (half the size it would take J2ME to do it as a function call).

These bytes tell it:

  1. the kind of element (TextRect)

  2. an ID label so that script can interact with it and other elements can lay themselves out relative to it

  3. a bunch of modifier bits to control its behavior (including left, right or center alignment, should scrolling it wrap around the ends or pin)

  4. which text string to display

  5. at what location relative to some other element on the screen (which means it automatically adjusts to different size screens when the other elements are smaller or larger graphics).

  6. how much size to reserve for this element in x and y

  7. what font to use (a font includes custom graphics for regular and highlight state)

  8. the current scroll and limit (text too big for a field can be scrolled by line or by page)

The third design decision was to make screen layout relative. FLIRT display elements are designed to be laid out in a relative manner, autolaying themselves out as appropriate for different size screens and data.

Events include softkey events, keypad events, and pseudo events the user can create. Since there are no local variables, there are no “calling arguments” either, except that you set up some reserved spots in the global data arrays to be used in the call. Hence triggering an event and making a subroutine call to event code of some state use the same mechanism.

FLIRT acts as our common library resource, in that sections of it can be compiled in or out, including custom fonts and textwrapping, networking, sorting, and RMS (file) access. Interface elements include textblocks, horizontal and vertical menus, marquees, graphics, scrollbars, screen keyboard, clipping areas, and camera abilities.

The fourth design decision was to make scrolling a fundamental metaphor over all graphical elements. In combination with scripts Flirt supports scrolled graphics (including animation), scrolled text, scrolled shapes (e.g., progress bars). Scrollbars following a display element automatically reflected the scroll state of that element, allowing you to have classic vertical scrollbars or horizontal scrollbase with text labels (like captions) for the current state of a scroll.

LimeLife products, being aimed at the women’s market, have a heavy amount of esthetic design, so simple menus just are plain unacceptable. The emulator screen at right is of LimeLife’s Instyle product. The menu is not a single menu element, it is composed of display elemets including character elements (the numbers in blue), text elements (the menu entries in black), and colored shape elements (highlights and separator bars). A router element controls behavior among the display elements. It names a list of other elements and as you scroll the router, you change which other element is selected (highlighted) by it.

This screen with its routers takes about 70 individual elements to compose it (where half of them are control or non-visible layout elements like an element which evenly spaces out a collection of elements vertically). The screen will automatically re-lay itself out if the graphic size or font size changes (or even if the graphic is missing because the network connection failed). It works on all screen sizes and on BREW or J2ME phones.

The script code for this state reacts to arrows, numbers for quick access, softkeys, and caches the main graphic in RMS if it can. The entire state description is 1093 bytes (script + display elements), which makes it one of the more complex states (since the average is 219 bytes per state). The product has 83 states taking 18,169 bytes (that’s display elements and script, and does not include text or images).

Having code and display information in one place (the state description) is a lot handier than our old J2ME-coded applications, where display code went in one big switch statement and control code went in different switch. It was hard to see how one related to the other. ( J2ME size issues incline one to write non-object oriented code in massive switch statements.)

Because all screen elements and script code is just “data”, new or revised states can be downloaded from the server if desired.

New product mockups can be rapidly created with FLIRT. It took a week to create a full-fledged visual demo of our second Flirt-based product (visual in that the controls only acted to take you from screen to screen and had no other functionality). When the BREW FLIRT engine was built, three completely different FLIRT-based products ran on it immediately. One merely took the data files built for the J2ME engine and ran them on the BREW one. Autolayout screens and all scripts ran correctly.

Conclusion:

Writing a new scripting language is a major undertaking, which goes far beyond merely coding it up. But when you have a really compelling reason to do so, you are not reinventing the wheel. You are creating a way to concisely express your thoughts in a new language. And language is what gives humans enormous leverage over the universe.

About the Author

I am both a consultant and an employee (in all cases, as a long-distance telecommuter, living in Hawaii in the past to Gloucester, UK by the time this article is uploaded). Want to reach me? gowilcox@gmail.com or look at my resume on Gamasutra.




join | contact us | advertise | write | my profile
news | features | companies | jobs | resumes | education | product guide | projects | store



Copyright © 2006 CMP Media LLC

privacy policy
| terms of service