Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
GameWeaver: a Construction Kit for Kids to Create Video Games for Handheld Devices
by
Alice (Yu) Yang S.B., Computer [Electrical] Science and Engineering, 2000
Submitted to the Department of Electrical Engineering and Computer Science
in Partial Fulfillment of Requirements for the Degree of
Master of Engineering in Electrical Engineering and Computer Science
at the Massachusetts Institute of Technology
Feb 2001
Copyright 2001 Alice (Yu) Yang. All rights reserved.
The author hereby grants to M.I.T. permission to reproduce and distribute publicly paper and electronic copies of this thesis
and to grant others the right to do so.
Author ________________________________________________________ Department of Electrical Engineering and Computer Science
Feb 2, 2001
Certified by ____________________________________________________ Bakhtiar Mikhak
Thesis Supervisor
Accepted by ____________________________________________________ Arthur C. Smith
Chairman, Department Committee on Graduate Theses
GameWeaver: a Construction Kit For Kids to Create Video Games For Handheld Devices
by
Alice (Yu) Yang
Submitted to the Department of Electrical Engineering and Computer Science
Feb 2, 2001
In Partial Fulfillment of the Requirements for the Degree of Master of Engineering in Electrical Engineering and Computer Science
ABSTRACT
Over the past three decades, constructionist research on learning and epistemology has provided us with much evidence that children learn most effectively when they are engaged in making things that they care about. In light of the deep affective and sometime cognitive relationship that children grow up playing videogames, we have a rare opportunity to help children connect to many important ideas that go into the design and construction of videogames. The research presented in this thesis, inspired by the existing research on how and what children learn in constructing their own videogames, provides a new set of tools, called GameWeaver, designed particularly to enable children and other novices to design and build their own videogames. Mindful of the growing presence of all types of more and more powerful handheld devices, we designed GameWeaver such that all games made with it can be run on Palm Pilots, PocketPC machines, and Color Gameboys as well as on desktop computers. In addition to the design and implementation of GameWeaver, we present the design and construction of a few classic arcade-style games such as Pacman and Pong with GameWeaver in detail. We also discuss how future versions of GameWeaver can be extended to allow children build their own controllers and real-time feedback mechanisms for their games by interfacing their handheld devices with the MetaCricket system of programmable bricks. Thesis Supervisor: Bakhtiar Mikhak Title: Research Scientist, MIT Media Laboratory
Table of Contents
List of figures ...................................................................................................................... iii
Acknowledgments.............................................................................................................. iv
C h a p t e r 1 Introduction ........................................................................................... 1
C h a p t e r 2 Motivation .............................................................................................. 4 2.1 Why Construction Kits? ............................................................................... 4 2.2 Why Videogames? ......................................................................................... 5 2.3 Why handheld devices?................................................................................. 6
C h a p t e r 3 Previous work ........................................................................................ 9 3.1 Programming Construction Kits ................................................................ 9
3.1.1 Logo .......................................................................................................... 9 3.1.2 Agentsheets and Cocoa (Kidsim) ......................................................10
3.2 Videogame Construction Kits...................................................................11 3.2.1 Pinball Construction Set......................................................................12 3.2.2 “Click” Series.........................................................................................12 3.2.3 Stagecast Creator...................................................................................13
3.3 Construction Kits for Handheld Devices ...............................................14 C h a p t e r 4 Design....................................................................................................16
4.1 Game Design Space ....................................................................................16 4.2 Game Components and Representation (Sample project: Pacman)..19
4.2.1 Graphical Components .......................................................................20 4.2.1.1 Tiles................................................................................................21 4.2.1.2 Shapes............................................................................................22 4.2.1.3 Backgrounds.................................................................................24
4.2.2 Programming Components ................................................................26 4.2.2.1 Procedures ....................................................................................26 4.2.2.2 Event Handlers............................................................................28
4.2.3 Sprites and Characters .........................................................................31 4.2.3.1 Observer (the special sprite)......................................................34
4.3 Programming Language..............................................................................35 4.3.1 Text-based vs. Graphical.....................................................................36 4.3.2 Compiled vs. Interpreted ....................................................................37 4.3.3 Detailed Specification ..........................................................................39
4.3.3.1 Data Types ...................................................................................39 4.3.3.2 Variables........................................................................................39 4.3.3.3 Operators and Expressions.......................................................40 4.3.3.4 Control Statements .....................................................................41
ii
4.3.3.5 Procedures ....................................................................................41 C h a p t e r 5 Implementation ...................................................................................43
5.1 Overall System..............................................................................................43 5.2 IDE (Integrated Development Environment).......................................44
5.2.1 GUI .........................................................................................................45 5.2.2 Game Objects Layer ............................................................................46 5.2.3 Interpreter ..............................................................................................47
5.2.3.1 Byte Codes....................................................................................47 5.2.3.2 Interpreter Implementation for IDE ......................................48 5.2.3.3 Interpreter Implementation for Handheld Devices .............49
5.2.4 Compiler.................................................................................................50 5.2.4.1 From Source Code to Byte Code.............................................50
5.2.5 GWE (GameWeaver Executable) file ..............................................57 5.3 A Sample Byte-Code Interpreter: Game Interpreter for the Palm Platform .......................................................................................................................57
5.3.1 Palm Application: GameWeaver.prc.................................................58 5.3.2 Conduit: GameCond.dll ......................................................................61
C h a p t e r 6 Conclusion............................................................................................65
APPENDIX I: Byte Codes ........................................................................................67
APPENDIX II: Grammar ......................................................................................71
APPENDIX III: Stored Procedures .......................................................................72
APPENDIX IV: Gwe file format ...........................................................................74
APPENDIX V: Symbols Used In Parser Implementation...............................77
APPENDIX VI: List of Tree Nodes......................................................................78
APPENDIX VII: Pong (Breakaway)........................................................................79
Bibliography .......................................................................................................................88
iii
LIST OF FIGURES
Number Page Figure 1: Images created using Logo using the commands “forward 50” (left) and
“repeat 36 [right 10 repeat 4 [forward 50 right 90]]” (right). .......................10 Figure 2: Examples of graphical rewrite rules in Cocoa (Kidsim) ............................11 Figure 3: Pinball construction set (mac version) ..........................................................12 Figure 4: Multimedia Fusion’s event editor (top) uses a spreadsheet layout for
linking objects (horizontally displayed) to conditions (vertically displayed), while the storyboard editor (bottom) allows users to edit frames. .............13
Figure 5: A ladder maze game created using Stagecast Creator (by David Senef).14 Figure 6: Required expertise/knowledge vs. development time for making
different types of games......................................................................................17 Figure 7: Learning rate vs. development time for different types of games. ..........18 Figure 8: Hierarchic structure of game components...................................................20 Figure 9: “Edit Tiles” window for Pacman game ........................................................21 Figure 10: “Edit Shape” window for Pacman game....................................................23 Figure 11: “Edit Shape” window for Tetris game........................................................23 Figure 12: “Edit Background” window for Pacman game.........................................25 Figure 13: Procedure definitions for the pacman sprite in the Pacman game........27 Figure 14: Example of an action (event-handlers) for ghost sprites in Pacman
game........................................................................................................................28 Figure 15: Flow chart representing sprite foo...............................................................30 Figure 16: Examples of how two counters for detecting the number of collisions
can become out of sync ......................................................................................31 Figure 17: Properties panel for pacman sprite..............................................................33 Figure 18: Observer in Pacman Game...........................................................................35 Figure 19: Overall system design involving a platform independent IDE and
interpreters for individual handheld devices...................................................43 Figure 20: Block diagram representation of the four main components of the
IDE.........................................................................................................................45 Figure 21: Compiler Implementation represented in three stages ............................50 Figure 22: Parser implementation using JLex and Java Cup......................................51 Figure 23: Parse tree corresponding to source code: "if (x>0) { fd(x+1) }"..........52
iv
ACKNOWLEDGMENTS
I would like to thank my advisor, Bakhtiar Mikhak, for guiding me through this
yearlong project, contributing valuable ideas, providing inspiration, and being so
encouraging and supportive throughout all stages of this project. Thanks to
Mitchel Resnick, for introducing me to the Epistemology and Learning Group at
Media Lab, and for helping define the scope of this thesis project early on. I’d
also like to send thanks to Brian Silverman, for providing his expertise and
knowledge and contributing alternative ideas ever since the early stages of this
project.
There are also many colleagues at Media Lab I’d like to thank, such as my
previous officemates Michelle Shook and LaShaun Collier, or making me feel at
home when I first joined the group. Thanks to Fred Martin and Rick Borovoy
for suggesting alternative ideas for this project, and Anthony Hui and Oludotun
Fashoyin for offering expertise on implementation issues.
To my parents: thank you for all your love and support ever since I can
remember. To all my friends at MIT, thank you for making the past four and a
half years such a wonderful experience for me. I will truly miss all of you.
Last but not least, I send a special thanks to James, for making me rethink many
ideas in this thesis, for helping me with implementation issues, and for always
being there. In so many ways, I couldn’t have done it without you.
C h a p t e r 1
INTRODUCTION
“Across the world children have entered a passionate and enduring love affair with the computer. What they do with computers is as varied as their activities…The love affair involves more than the desire to do things with computers. It also has an element of possessiveness and, most importantly, of assertion of intellectual identity. Large numbers of children see the computers as “theirs”—as something that belongs to them, to their generation.”
Seymour Papert in Children’s Machine (1993) In the past few years, small computational toys such as Gameboy™,
Tamagochi™, Cybiko™, Friend.link™, and Groove Connection™ have taken
children’s relationship with computers to a new level. They now play and act out
nurturing games, keep in touch and interact with their friends, and more broadly
learn about themselves and the world with and through their machines. This
diversity in children’s interests in and expectations of their handheld computers
has produced a growing market for a large number of specialized devices.
Inspired by images of the relationship between children and computers presented
by Seymour Papert (Papert 1980, Papert 1993), Constructionist learning
researchers have been addressing this demand by creating new computational
construction kits that provide children with a set of tools for building and
reconfiguring their own handheld and wearable devices (Mikhak, Martin, Berg,
Resnick and Silverman 1999, Martin, Mikhak, Resnick, Silverman, and Berg 2000,
Martin, Mikhak, and Silverman 2000) as well as extending the capabilities of the
existing handheld devices1. What makes this approach particularly appealing is
1 Website: http://llk.media.mit.edu/people/mikhak/projects/
2
that it provides a natural context for many new Constructionist learning
opportunities (Mikhak, Martin, Berg, Resnick and Silverman 1999).
Constructionism, as a theory of learning and a strategy for education, is based on
two different senses of "construction." It is grounded in the idea that people learn
by actively constructing new knowledge, not by having information "poured" into
their heads. Moreover, it asserts that people learn with particular effectiveness
when they are engaged in "constructing" personally meaningful artifacts (such as
computer programs, animations, or robots).
This thesis presents the design and implementation of a new constructionist tool,
called GameWeaver, that takes advantage of the recent growth in popularity and
computational power of handheld devices as well as the previous work of our
group (The Lifelong Kindergarten group at the MIT Media Lab) in supporting a
rich learning experience through videogame design and construction.
GameWeaver is a software environment that allows children to build videogames
that they can not only run on desktop computers but also on almost any portable
computers, including laptops, PocketPC™ machines, Palm Pilots, Cell phones,
digital cameras, and Color Gameboy™s.
The portability and communication capabilities of these devices provide a great
incentive for children to create their own videogames in order to share and play
them with their friends. Prior research on what children learn from designing and
making videogames has a very long history in our group and forms the theoretical
foundation of the work presented here.
In particular, this thesis aims to extend the main results of the prior research by
showing that in the process of building their own videogames, children not only
learn about proposing and managing their own projects as well as advanced
mathematical and programming concepts (Kafai 1993), but also come to
3
appreciate the fundamental universality and transferability of ideas between the
multitude of computational platforms that they encounter everyday. We believe
that such activities and experiences can bring deep conceptual order to the
apparent diversity and complexity of digital technologies, and will play an
important role in helping children develop a true literacy about the digital world
in which they live.
In the next chapter, we will discuss the motivations for this work in greater detail.
In chapter 3, we will discuss prior and related research in this area. Chapters 4
and 5 present a detailed description of the design and implementation of the
GameWeaver development environment respectively. In Chapter 6, we present a
couple of the future directions that we are beginning to pursue, our conclusions
and some closing thoughts.
4
C h a p t e r 2
MOTIVATION
2.1 Why Construction Kits?
The research presented in this thesis is guided by the constructionist theory of
learning, which asserts that knowledge is not simply transmitted from teacher to
student, but is actively constructed by the mind of the learner, and builds upon a
large body of constructionist learning research which suggests that learners are
particularly likely to create new ideas when they are actively engaged in making
external artifacts that they can reflect upon and share with others (Harel and
Papert, 1991 and Kafai and Resnick, 1996). One of the most effective ways to
engage children in designing and making things is to provide them with powerful,
carefully designed construction kits that help them create their own video games,
robots, and simulations. By studying children’s work with these construction kits,
constructionist researchers probe how and what children learn through the
process of designing and making.
With constructionism as a theoretical framework, and the previous research on
the tools that were designed to enable children to make their own videogames as
an empirical foundation, the goal of my research was to design a new
programming language that allows children to design videogames that takes
maximum advantage of the computational resources, input modalities, and
display capabilities of the many handheld computers that are in their lives today.
The design of the programming language presented here is mindful of, and allows
for, the possibility of extending this work to a much more general construction
kit that would allow children to make their own interfaces and game controllers
5
with the MetaCricket construction kits (Martin, Mikhak, and Silverman 2000). We
envision that a future version of the software environment presented in this
thesis will allow children to specify how they have constructed their own
interfaces and how their games should take advantage of it.
2.2 Why Videogames?
Constructionism emphasizes that projects children build should be personally
meaningful, so learners can make deep personal connections with the ideas being
learned (Papert 1991). There is almost no better candidate for such projects than
video games, for two reasons.
First, children love video games. Ever since the dawn of the first arcade games –
such as Pacman – in the early 70’s, videogames have become an essential
connection between kid culture and the larger grownup culture of which the
videogame culture is a part. Children today not only belong to and shape this
videogame culture, but also create and take part in very rich social networks that
have grown out of and around this culture. Not only do children enjoy playing
video games on their own and with their friends, but they also love watching
others play and talking about the many intricacies of the games. And, since
videogames are generally considered a “play” activity, kids seek every opportunity
to get their hands on a keypad or a joystick and use these games to connect to
other kids, and actively participate in the world of many of the adults around
them. Parents also have recognized the power that these games hold over their
children and they use these games to connect to their children. For example when
I was a kid, my parents used playing video games (and watching TV) as “rewards”
for good behavior. I have to say it was pretty effective!
Over the past few decades, even though video games have diversified into many
forms, from mind-crunching role-playing games (Myst) to intense shoot-them-up
6
3D games (Quake), from console-based games (Super Mario) to real life
simulation games (Flight Simulator), video games have only become more
accessible and popular among children. Also within the last decade, with the
advent of internet, on-line games have become very popular and have created
thousands of game communities on the web, most of which consist of kids,
opening up new means of communication, interaction, and cooperation between
kids and adults in a safe play-ground.
Second, constructing video games can be a rewarding learning experience for
kids. Seymour Papert was one of the first people that thought computers could
be excellent materials for constructionist activities. He argued that through
writing computer programs, a child’s thought process becomes more concrete
and explicit, and hence more accessible to reflection (Papert 1980). Since video
games are essentially computer programs, creating videogames have proven to be
a very rich learning experience (Kafai 1993).
2.3 Why handheld devices?
The last two sections argued that video game construction kits are great learning
tools for children. These are not new ideas however, and many researchers,
educators, and even industrial professionals have built different type of video
game construction kits (discussed in detail in section 3.2), to test out these ideas.
What differentiates GameWeaver from others is that the videogames created in
GameWeaver are targeted for palm-size handheld devices, such as Palm Pilots,
Visors, PocketPC™ machines, and Gameboy™s.
Acknowledging the appeal and importance of general-purpose design and
development tools for handheld devices, we also believe that there is a great
opportunity to develop many special-purpose development tools for handheld
7
devices to support different learning activities2. With such a collection of such
tools at hand, we believe that children will develop a deep and lasting cognitive
and affective relationships with handheld computers (even those targeted at adult
professionals) thanks to the many play and learning scenarios that they can
imagine and realize. Since we suspect that these scenarios will take advantage of
the portability, expandability, and wireless communication abilities of these
devices in novel ways, let us examine the play and learning potential of each of
these capabilities in turn.
First, due to their portability, handheld devices are great for playing games. Take
Nintendo’s Gameboy™ for example, it was a handheld device specially designed
for playing games. Even though pc-games and console-games have much bigger
screen size, higher resolution, and better sound effects compared to Gameboy™,
Gameboy™ still became a popular product because it allows children (and adults)
to conveniently bring games with them to school, on trips, or anywhere they go.
Even though the main purpose of other handheld devices such as Palm Pilots
and PocketPC™ machines are not for playing games, they are still attractive
gaming devices. In fact, they are both sold preloaded with a few simple games,
and yet they still don’t satisfy the general public’s appetite for games. One
consequence of this is that creating games for these platforms is a hot area of
research among amateur developers today.
Second, the expandability of certain handheld devices allows users to create
hardware interfaces to their games. The trend of handheld computing devices
today is they are becoming more and more expandable, allowing a wide range of
attachable add-ons, such as GPS systems, additional memory, etc. Most of them
use standard hardware interfaces, such as serial ports, infrared ports, and
2 For a few examples of such construction kits and development tools see the Lifelong Kindergarten projects
web site at http://llk.media.mit.edu/projects/
8
expansion ports for PCMCIA card, which open the door to a wide variety of
sensing, display, and communication devices. These standard interfaces allow
children to easily attach additional hardware devices, such as joysticks, motors,
and sensors to their games, giving interactive games a completely new meaning.
Imagine children making a version of the classic game Pacman, where whenever
Pacman collides into the wall, a motor will turn on to cause a vibrating motion in
handheld. One of the future directions for this project integrates handheld
devices into the MetaCricket system to allow children to design their own
interfaces for their videogame.3
Last but not least, even though most games that run on handheld devices today
are single player games, it does not mean that multi-player games cannot be
implemented on these devices. In fact, the wireless communications system on
many handheld devices (such as the IR port or the PCMCIA wireless LAN cards)
open opportunities for children to create games that can communicate between
different devices, bringing more interaction into games, even allowing children to
create multi-player games. Multi-player games are not only more interesting to
play, but also more challenging to build, especially ones that run on handheld
devices. They also provide a much wider design space than single player games,
encouraging more creativity. Therefore, there is still a lot of potential in creating
interesting games on handheld devices. One of the goals of this project is to
design a language that makes designing multi-player, multi-device games easier for
novices.
The above discussions have provided us with the motivation as well as the
educational/learning and technical justification for research on making handheld
devices a target platform for videogame construction kits.
3 Website: http://llk.media.mit.edu/projects/videogame/
9
C h a p t e r 3
PREVIOUS WORK
This chapter discusses some examples of different computational construction
kits that have been built for children to date. We first take a look at general-
purpose programming construction kits such as Logo, and then proceed to more
domain specific video game construction kits. In the end, we look at a few
construction kits created specifically for handheld devices.
3.1 Programming Construction Kits
3.1.1 Logo
Researchers have developed several types of general-purpose programming
construction kits in order to enable children to engage in their own design
activities. One of the earliest of these construction kits is Logo. Logo is a
programming language created especially for children by a team of researchers
including Seymour Papert in the late 1960’s. Compared to regular programming
languages, Logo is simpler in syntax and more similar to a natural language, hence
more accessible to children. Logo is a subset of Lisp and can be used as a serious
programming language, but it is best known as a language for creating graphics.
Children program a cursor (called a “turtle”) to draw figures on the screen. Logo
is also ideal for simulations and AI applications. Logo’s main features are
modularity, extensibility, interactivity, and flexibility.
10
Figure 1: Images created using Logo using the commands “forward 50” (left) and “repeat 36 [right 10 repeat 4 [forward 50 right 90]]” (right).
As Logo became more popular among kids, researchers created many types of
construction kits based on the essential ideas of Logo and constructionism. Such
construction kits include LEGO Logo, MicroWorlds, and StarLogo. LEGO
Logo, created by Mitchel Resnick and Steve Ocko at MIT Media Lab, provides a
special interface for controlling motors, sensors, and lights built out of LEGO
bricks. MicroWorlds, released by LCSI4 (Logo Computer Systems, Inc.) in 1993,
introduced multi-tasking and parallel processing into the Logo language.
StarLogo (Resnick 1994), developed by a team led by Mitchel Resnick at MIT
Media Lab, is a massively parallel version of Logo designed to facilitate the
simulation and exploration of decentralized systems.
3.1.2 Agentsheets and Cocoa (Kidsim)
Agentsheets, created by Alex Repenning at the University of Colorado
(Repenning, 1994), enables children to design their own StarLogo-like simulations
using a rule-based graphical programming language. Cocoa, created by David
Smith, Allan Cypher, and Jim Spohrer at Apple Computer (Smith, Cypher,
Spohrer, 1994), enables children to make their own Logo-like programs and
games graphically in the programming-by-example paradigm.
4 Website http://www.microworlds.com
11
Unlike Logo and most other traditional programming tools, Agentsheets and
Cocoa (KidSim) use a totally different approach to programming. They chose
not to use any textual programming language, hence getting rid of programming
syntax, which is most troublesome to learn for younger kids. Instead, behavior of
characters (agents) is defined through graphical rewrite rules, such as the ones
shown in Figure 2.
Figure 2: Examples of graphical rewrite rules in Cocoa (Kidsim)
This type of programming using graphical rewrite rules has proven to be popular
among elementary school kids, but it has the disadvantage that the complexity of
a program (measured by the number of rules required to define it) grows
exponentially with the number of characters in a project.
3.2 Videogame Construction Kits
This section discusses three popular videogame construction kits for children, the
Pinball Construction Set, the Klik & Play series of construction kits, and
Stagecast Creator.
12
3.2.1 Pinball Construction Set
The Pinball Construction Set is one of the earliest video game construction kits
created. It was designed and implemented by Bill Budge of Electronics Arts in
1983. It allows children to create their own pinball games by dropping parts
(bumpers, pins, racks, and flippers) onto the play table, or even alter the table
itself. It also allows users to alter the physical properties of the world such as
gravity, bounce, kick, and speed. Children can also paint their own custom
backgrounds for the play table.
Figure 3: Pinball construction set (Mac version)
The Pinball Construction Set can be considered a work of art that was ahead of
its time. Despite the fact that the display was in black and white, the pinball
games themselves were fun to play, and making ones own pinball game was
simply a blast. It had some problems however; for example, multiple balls
sometimes rolled over each other and balls could also get caught in infinite loops.
I think these flaws actually point at strength as far as learning is concerned.
3.2.2 “Click” Series
Klik & Play, published in 1994 by Europress Software Ltd, was the first product
of the “Click” series of software tool products for creating arcade, adventure, and
platform games. This series include Games Factory, Click & Create, and the
latest version of Multimedia Fusion by the Clickteam in 2000.
13
Figure 4: Multimedia Fusion’s event editor (top) uses a spreadsheet layout for linking objects (horizontally displayed) to conditions (vertically displayed), while the storyboard editor (bottom) allows users to edit frames.
In the “Click” series of video game construction kits, children create games
through dragging and dropping predefined objects from an object library
(containing thousands of objects) into frames. There are also storyboard and
level editors for creating multi-level games. No programming language is
necessary in defining behavior of objects since all properties of objects are
predefined. The user simply chooses which properties their characters should
have. This way of “programming” is simple enough so children with very little
technical background can create games, but is also limited in the type of games
than can be created, and therefore lessens the educational value of the
construction kit.
3.2.3 Stagecast Creator
Stagecast Creator, published by Stagecast Software Inc in 1999, was designed to
allow kids to create games, puzzles, and interactive stories on the web. It provides
graphical tools that enable the creation, play and modification of interactive and
engaging simulations, models, games, stories, and lessons, collectively called
“Sims”. These Sims can be played on a Web page, or downloaded for local play
on Windows, Macintosh and UNIX computers. Children can also specify rules
of behaviors for their animated characters through both graphical tools and the
simple programming language Cocoa.
14
As a piece of educational software, Stagecast Creator has received many
appraising reviews from being used both in classrooms and at home. It does
have some drawbacks however. For example, Stagecast Creator is supposedly
suitable for ages 5 to 18, but its interface is far too complex for the younger kids
to use. Stagecast recently teamed up with Classroom Connect to bring the
benefits of Creator to kids learning communities online.
Figure 5: A ladder maze game created using Stagecast Creator (by David Senef)
On a side note, before Stagecast Creator was created, other similar projects had
already taken place in the research field. One of these was that of Andrew Begel:
the Bongo project, a programming environment of kids to create video games on
the web (Begel, 1997). Bongo uses a programming language called Yoyo that
implements a version of Logo on top of Java.
3.3 Construction Kits for Handheld Devices
At the time of writing this thesis, there are no known construction kits for
children to create applications for handheld devices such as Palm Pilots and
PocketPC™s, for several reasons. First of all, today’s handheld industry is in a
developing stage where standards are still being formed. It was only within the
last few years that development tools have become available for advanced
programmers to create realistic applications for handheld devices. Second, since
handheld computing devices aren’t considered cheap yet, it is still rare for
children to own their own palms or PocketPCs, hence there has been no real
15
demand for any such construction kits for children yet. But with prices of
handheld devices dropping each year (Palm’s m100 is now being as targeted
towards high school kids), it is only a matter of time that eventually kids will own
their own Palm Pilots.
There are, however, a lot of adult hobbyist game developers out there for
handheld devices. Most of the popular games are arcade type single player games
such as Minesweeper and Pacman. There are also some two-player games, such
as Ping-Pong (a two-player version of Pong), that uses the IR port to
communicate between two handheld devices.
We anticipate that in the near future Palm Pilots and PocketPC™s, much like
Gameboy™s, will be widely available to children. There will therefore be an
opportunity to provide kids and novices with a set of tools for developing their
own applications in general and videogames in particular. This thesis focuses on
one such tool.
16
C h a p t e r 4
DESIGN
This chapter explains the design of GameWeaver from three aspects. First, from
the point of view of the player of a game, the game design space section talks
about what type of games can be made using GameWeaver. Second, from a game
creator’s point of view, the game components and representation section talks
about how to build games using the basic building blocks provided by
GameWeaver. To illustrate things more clearly, this section also used the classic
Pacman game as an example in many places. Third, from a programmer’s point
of view, the programming language section gives a detailed description of the
language used in GameWeaver, which is especially designed for children to create
games. In each of these sections, we give arguments of why certain designs were
chosen over alternative ones.
4.1 Game Design Space
This section talks about what type of games kids can make with GameWeaver.
After presenting the possible choices: arcade games, 2D platform games, and 3D
games, we discuss the pros and cons of each of these games from both a player
and the developer’s point of view of the game. We conclude that arcade games
are the best choice from the learning standpoint.
From the players’ perspective, the most popular games today can be categorized
into three categories: arcade games, 2D platform games, and 3D games. Arcade
games, such as Pacman, Breakaway, Space Invaders, and Tetris have been around
the longest (since 1970’s). Arcade games typically involve either capturing
/shooting the enemy or avoiding being captured/shot.
17
2D platform games, such as Mario Brothers, have been very popular in private
homes for almost two decades. Compared to arcade games, 2D platform games
generally have many more characters and levels, and involve an extensive
storyline. The tasks in 2D platform games are also more complicated and less
repetitive.
3D games, such as Quake, are the newest and require high performance systems
to support the high-quality graphics. They are usually role-playing adventure
games or mystery-solving games that have even fancier storylines than 2D
platform games. 3D games are most popular as on-line games where multiple
users can team up or play against each other.
Development time (t)
arcade
3D
Expertise/Knowledge (e)
2D platform
Figure 6: Required expertise/knowledge vs. development time for making different
types of games
From the game developers’ perspective, given a well-designed development kit,
the videogames today can be analyzed in two regards: the minimum amount of
expertise/knowledge the developer needs to design the game, and the time
required to make the game. Arcade games are least demanding in both expertise
and time, while 3D games are the most demanding, and 2D platform games sit
18
somewhere in between. However, the additional amount of time required in
making a 3D/2D platform game as opposed to an Arcade game, is significantly
more than the additional amount of expertise needed, because most of the work
in making large-scale games are repetitive work. This relationship is also
illustrated in Figure 6.
Learning rate (de/dt)
Development time (t)
arcade 3D 2D platform
Figure 7: Learning rate vs. development time for different types of games.
Finally, let us compare the educational value of constructions kits that support
these 3 types of games. Notice in the above figure, the derivative de/dt can be
interpreted as the learning rate, since it represents the amount of expertise a child
needs to acquire to make any progress in their game development. We can plot
this learning curve out, as in Figure 7, and see that this learning curve flattens out
and diminishes as games become more complex. Hence large-scale games such as
2D platform and 3D games do not have as much educational value as arcade
games. This is one of the main reasons we chose arcade games as the targeted
design space for GameWeaver.
19
On a side note, some 2D platform and 3D games might be too computationally
intensive for handheld devices to handle, and even if they can be run on a
handheld device, most of their fancy graphical effects wouldn’t be appreciable on
a 3-inch screen. Hence arcade games are also a better match to the platforms that
we are interested in working on. This may partially explain why arcade games,
even though they have been around for decades, are still popular today, especially
on handheld (gaming) devices.
4.2 Game Components and Representation (Sample project: Pacman)
As a programming system, a game construction kit such as GameWeaver must
support some level of abstraction for users to define their programs. This section
talks about the abstract components used to construct games in GameWeaver
and how these components relate to each other. We will use the classic Pacman
game as an example in many places.
Games in GameWeaver consist mainly of Tiles, Shapes, Backgrounds,
Procedures, Actions (Event-handlers), and Sprites, defined in the table below.
Name Definition Tile An 8x8 pixel image Shape An image consisting of one or
more tiles, used for defining appearance of sprites
Background A 20x18 grid of tiles Procedure Basic programming component Action (Event-handlers)
A programming component for handling events
Sprite A game character that has certain behaviors and attributes associated with it
Table 1: Definition of game components
20
These game components form a hierarchical structure since some are used for
building others. For example, sprites consist of shapes, procedures, and events, while
shapes and backgrounds are both further made of tiles. These relationships are
more clearly shown in Figure 8. More specifically, backgrounds, tiles, and shapes
are merely graphical data objects (diagonal fill) for defining appearance, while
procedures and events are actual programming components (cross-hatch fill) for
defining behavior, and sprites and games are complex objects that have both
appearance and behavior (no fill).
Game
Sprite Background
Tile
Shape Procedure Event
Figure 8: Hierarchic structure of game components
The next sections explain each of these components in detail.
4.2.1 Graphical Components
This section covers the graphical objects Tile, Shape, and Background, which are
used for defining the appearance of a game.
21
4.2.1.1 Tiles
GameWeaver uses a tile-based schema to define the appearance of games, i.e. a
tile is the smallest unit for display that can be altered while the game is running.
The game screen is divided into tiles that are 8x8 pixels large. Tiles can be
repeatedly used as building blocks for defining both shapes and backgrounds;
therefore tiles are usually the first things to define in creating a new game.
To create new tiles or edit existing ones, use the “Edit->Tiles” menu item to
bring up the “Edit Tiles” window, which contains a list of all the tiles in the
current project, a color chooser, and a tile editor for drawing tiles on a pixel level,
As show in Figure 9, the Pacman game is defined using seven different tiles.
Figure 9: “Edit Tiles” window for Pacman game
22
The color chooser has up to 117 colors of varying hue, saturation and brightness,
which should be sufficient for arcade style games.
We chose such a tile-based display system for several reasons. First, tiles offer a
simple but useful level of abstraction for representing a part of a background.
This abstraction allows game characters to easily distinguish one part of the
background from others, hence giving them “meaning”. Second, it conforms to
the display standards of Gameboy™, a popular handheld device. Third, using
tiles to “draw” backgrounds is much more efficient than drawing them pixel by
pixel, under the condition that tiles are repeatedly used in the background, which
is true for most arcade games.
4.2.1.2 Shapes
Shapes are used to define the appearance of sprites (characters) in a game. One
important feature of shapes is that they consist of a partially occupied grid of tiles.
This gives the game creator flexibility since they may want to have shapes of
variable sizes.
Shapes are defined in the “edit shapes” window, as shown in Figure 10 and
Figure 11. This window allows users to both create new shapes and edit existing
ones. It consists of three parts: a list of all game shapes (left column) allowing
users to choose which shape to edit, a palette of all current game tiles (middle
column) allowing users to choose which tile to use for drawing the currently
selected shape, and an editable grid of the selected shape (right column), which
can be painted using the selected tile. We can see from Figure 10 that a Pacman
game character consists of a shape that is only a 1x1 tile, while Figure 11 indicates
that the blocks in the game Tetris consist of shapes that occupy varying parts of
the tile grid.
23
Figure 10: “Edit Shape” window for Pacman game
Figure 11: “Edit Shape” window for Tetris game
In this version of GameWeaver, shapes are limited to be of a maximum size of 4
by 4 tiles. There is no particular reason for such a limitation, and if necessary, the
maximum size of shapes can be easily expanded in the future. However having
24
larger shapes does impose a processing overhead for the game runtime in
processes such as detecting collision events.
The main reason for designing shapes to be variable size is that any restrictions
on the shape size directly affects the game design space. It is common for arcade
games to have characters of variable sizes, and some characters can even “grow”
or “shrink” at run-time (such as in Pong), hence setting shapes to be a fixed size
greatly limits the game design space. But fixed size shapes also have the
advantages of not having any of the complications that variable size shapes
introduce. These complications include: how to handle rotation of a sprite if its
shape is not square? What happens when a sprite’s shape needs to “grow” but
there is no space for it? And how to determine whether two sprites of different
size are colliding with each other?
4.2.1.3 Backgrounds
Before describing the details of Backgrounds, let us fist take a look at the
relationship between Shapes and Backgrounds. The overall display system in
GameWeaver consists of two layers, a foreground layer containing Characters
and their corresponding Shapes, and a background layer containing a single
Background object. Therefore, for each Character (that is not in invisible mode),
its shape always overrides the background that it occupies. The only
complication arises when more than one characters occupy the same space, at
which point any character’s shape can be the dominant one and hence displayed,
while the others aren’t.
The above relationship between shapes and backgrounds implies that while a
game is running, users have three ways of changing the display. One option is to
replace specific tiles in the current background with different ones. For example,
to simulate Pacman eating a dot, we can set the tile that Pacman just went over
from a “dot” tile to a “blank” tile. Another way is to load an entire different
25
background, which can be used for advancing to the next level in the game. We
can also change the display by moving characters (instances of sprites) around,
since sprites have shapes associated with them.
Shapes and backgrounds are very similar, except backgrounds are of a fixed size,
20 x 18 (tiles), which is the same size as the display screen on Gameboys™.
Figure 12 shows one of the backgrounds used in the Pacman game that
represents a maze.
Figure 12: “Edit Background” window for Pacman game
As mentioned earlier, GameWeaver is a purely tile-based system, in which
backgrounds can only be defined using tiles. One disadvantage to such a design
is that, since each tile need to be painted separately first, and then pieced together,
specifying an irregular background in which most tiles do not repeat themselves
(such as a photo image) is an extremely inconvenient task to do. A possible
solution to this problem is to change the definition of backgrounds so that they
consist of two layers: a tile-based layer (what we have now) on top of a pixel-
based layer. The IDE can supply an image loader so users can load external
26
image files for specifying the bottom pixel-based layer. We have left the
implementation of an image loader to a future version of GameWeaver.
4.2.2 Programming Components
Having looked at the graphical components for creating games, this section
proceeds to the programming components, Procedures and Actions (Event-
handlers), used for defining the behaviors of characters in a game.
4.2.2.1 Procedures
Procedures in GameWeaver are similar to procedures in most other
programming languages. There are two types of procedures, ones that kids create
themselves, called user-defined procedures, and ones that are built into the system,
called stored procedures, which can be used but not modified.
User-defined procedures are defined under the “procedures” tab in the main
window. As shown in Figure 13, the pacman sprite contains a single user-defined
procedure called run, which uses many stored procedures such as fd and
get_tile_at.
Stored procedures are similar to the API (application programming interface) for
some programming languages such as Java. But rather than being linked
dynamically to code at runtime, stored procedures in GameWeaver are compiled
inline at compile time.
27
Figure 13: Procedure definitions for the pacman sprite in the Pacman game
A sprite can contain as many user-defined procedures as desired, as long as one
of them is called run. This run procedure provides an entry point for
executing characters. Through out the lifecycle of a runtime character, its run
procedure is repeatedly being called by the system (the frequency of which
depends on the speed setting on the character). We can therefore think of the
run procedure as being executed in an infinite loop in its own thread. It is the
programmer’s responsibility to ensure that characters cooperate with each other,
i.e., each run procedure eventually exists.
28
The syntax and format of procedure declarations and procedure calls are
described in more detail in section 4.3.3.5.
4.2.2.2 Event Handlers
Unlike procedures, which are only executed when explicitly called, event-handlers
are pieces of code that can listen for certain events to trigger their execution. For
example, an event-handler corresponding to a “key pressed” event only gets
executed when that input key is pressed.
The first step for creating an event-handler is to specify the type of event it will
handle (using the “Object->Add Event Handler…” menu option). The current
version of GameWeaver supports two categories of events, user input events
(such as UpArrowPressed) and collision events (CollidesTile and CollidesSprite).
Collision events have an additional parameter indicating exactly the type of tile or
sprite that the current sprite is colliding into.
Figure 14: Example of an action (event-handlers) for ghost sprites in Pacman game
29
The next step for creating an event handler is to specify the code to be executed
after that event occurs (under the “actions” tab). For example, Figure 14 shows
an event-handler telling ghost characters to kill themselves after they collide into a
“red” pacman character. The actual triggering of events while a game is running
is handled automatically by the system.
After understanding what event-handlers are, one might ask why GameWeaver
chose to use them. Most traditional programming languages, such as LISP,
Pascal, and C/C++ do not explicitly support event handling, while other
languages such as Visual Basic and Java (at least the AWT component) have
many user input events built into the language, and also allows the user to create
user-defined events.
GameWeaver supports event handling for several reasons. First, it can reduce a
significant amount of coding for the user. There are many events that commonly
need to be detected in arcade games, e.g. the collision of two characters. Without
event-handling support, the only way a user can check whether a character has
collided into something or not is to write code that periodically verifies whether a
collision has occurred through comparing relative positions. This chunk of code
can get quite messy and is replicated any time a collision needs to be detected
between any two characters. By supporting event handling, GameWeaver
reduces the amount of user-defined code required to detect these types of events
to a bare minimum (zero).
Second, event handling improves the runtime efficiency of the compiled code.
This can be seen using the same example of detecting collision events. When
event handling is not support by the system, the code for manually checking
collisions needs to be run frequently, unnecessarily hogging valuable CPU time.
30
Last but not least, system level event handling guarantees synchronization
between characters. Let’s explain what we mean by synchronization here through
giving an example of how two characters can become out of synch if event
handling is not supported by the system and is implemented manually by the
user. Assume a “collision” event is defined by two characters occupying (either
completely or partially) the same space5, then the program flowchart in Figure 15
represents a sprite, called foo, that moves forward one step at a time and counts
the number of collisions it experiences.
Am I coll iding anybody else?
Increment counter
Move forward 1
yes
no
Figure 15: Flow chart representing sprite foo
At first glance, it’s seems that this code should work, i.e. the value of the counter
should equal the number of collisions occurred, but the following example shows
that after two such foo objects collide each other, it is possible that one of them
recognized the collision, while the other did not. Figure 16 shows such a scenario
involving two instances of foo sprite (a triangle and hexagon). Initially, the triangle
is trying to go east, while, the hexagon is trying to go west, and both of their
counters are set to 0. It is triangle’s turn to move. He goes forward one step, and
5 The exact definition of a “collision” event is a character attempting to occupy the same space (either
partially or completely) of that of another character.
31
occupies the same space as the square. Now, assume the triangle runs much
faster than hexagon, hence it is still triangle’s turn. Triangle sees that he is
colliding with hexagon, increments its counter to 1, and moves forward again,
before hexagon even had a chance to check for the collision. Hence we end up
in a state where the two characters’ counters are out of sync, i.e., the collision that
occurred between the triangle and the hexagon was counted by the triangle, but
not the hexagon.
counter = 0 counter = 0 counter = 0 counter = 0 counter = 1
Figure 16: Examples of how two counters for detecting the number of collisions can become out of sync
The underlying problem here is in a multi-threaded system, such as ours, each
instance of a sprite is running it’s own thread. Without some special language
support for handling events, it is difficult to synchronize the threads so that
multiple threads can detect the same event.
To solve this problem, GameWeaver explicitly supports event handling by
providing the user with a list of built-in events that the system is in charge of
recognizing, and allowing the user to specify event-handlers for each of these
events. If a user creates an event-handler for an event, GameWeaver
automatically calls that event-handler when the event occurs. Unlike how other
programming environments support events, GameWeaver does not allow users
to define their own events, since that requires a much more complex language.
4.2.3 Sprites and Characters
A sprite in GameWeaver is a game object that has some behavior associated with
it. For example, in the game Pacman there are two types of sprites: pacman, whose
32
behavior is to move in the direction that the player asks it to; and ghost, whose
behavior is to try and catch pacman. The behavior of sprites is programmed
using procedures and actions (event handlers), described earlier.
A runtime instance of a sprite is called a runtime character (or simply character). The
concept of sprites vs. runtime characters in GameWeaver is similar to that of
Classes vs. Objects (instances of classes) in Java. For example, when the Pacman
game is running, there is usually only one pacman character, but multiple ghost
characters running at the same time. Characters are closed entities that have full
local control over its own actions, but limited access to any global information,
and almost no control over other characters. For example, a character can
change its own position, but not those of others characters, at least not directly.
The only way characters can communicate with each other is through global
variables, discusses in more detail in section 4.3.3.2.
Other than procedures and events, sprites also contain some additional
properties, displayed under the “properties” tab, as shown in Figure 17. The top
text area allows users to define local variables, discussed in more detail in section
4.3.3.2. The bottom two multiple-choice lists define the sprites and tiles that a
sprite collides with. For example, Figure 17 indicates the pacman sprite only
collides with the tile “cross”, meaning that the system will ensure that a pacman
character can never occupy the same space as a “cross” tile. This mechanism in
this case prevents pacman from walking through walls, which are defined using
“cross” tiles.
33
Figure 17: Properties panel for pacman sprite
Why did we choose to use sprites as basic building blocks of games then? There
are several advantages to this game structure. First, it simplifies the game creation
process for the game developer. Creating a game is not an easy task, especially for
a child with little programming experience. They are used to looking at games
from the player’s perspective, and seeing a very complicated system where many
different interactions between game characters occur simultaneously. But
compared to figuring out how all characters should behave under all scenarios, it
is much easier to think about how an individual character should behave under
different circumstances. Hence letting sprites be the basic building blocks of a
game breaks down the complex problem of creating a game into many smaller
34
tasks of specifying behaviors of individual characters in a game, which are much
easier than the big problem. Second, even though sprites are abstract objects,
they resemble real-life objects such as humans and animals that can only “see”
what is around and near them, and only have control over one’s own behaviors.
This resemblance makes it easier for children to understand the concept of sprites
compared to other abstract programming concepts. Last but not least, since a
sprite is an independent entity that characterizes a type of behavior, it is the ideal
game component to share between children who are making games. Allowing
children to trade characters in a game encourages interaction and learning from
peers.
There are also a few disadvantages of using sprites. One disadvantage is that
sprites have limited information about other sprites and components of the game.
GameWeaver supplies the user with a fixed collection of procedures for sprites to
obtain external information. For example, if a sprite needs to know the number
of other characters alive in the game, it has to explicitly call the
get_number_of stored procedure. But unfortunately there are only a finite
number of such procedures, and for a sprite to obtain any additional information
would be close to impossible. Another disadvantage is it is difficult to program
sprites to communicate or cooperate with each other, since sprites represent a
decentralized system in which all intelligence is distributed among individual
characters in a game. But most arcade games are simple enough to be
implemented using sprites and no additional components.
4.2.3.1 Observer (the special sprite)
The observer is a special sprite that exists in all games. Similar to the main
method in Java or C, the run procedure in observer provides an entry point for
executing the entire game. The observer is always the first character that gets
created and executed. Unlike other sprites, observer’s run procedure is executed
35
only once, and that defines the lifecycle of the entire games. The observer can be
used for initializing the background, creating characters, controlling levels (for
multi-level games), etc. Figure 18 shows the run procedure for the observer used
in Pacman.
Figure 18: Observer in Pacman Game
4.3 Programming Language
This section discusses the programming language used for programming sprites.
We first give arguments as to why GameWeaver’s programming language is text-
based (as opposed to graphical) and compiled (as opposed to
interpreted/scripting), and then we give a more detailed specification of the
definition of the language.
36
4.3.1 Text-based vs. Graphical
In the video game construction kits discussed in section 3.2, both text-based and
graphical programming languages were used. For example, Bongo uses a text-
based language similar to Logo, while Klik & Play uses graphical rewrite rules for
programming characters.
Text-based and graphical languages each have their advantages and disadvantages.
Most practical programming languages for adults are text-based, but beginner
programmers usually have difficulty getting the syntax and grammar correct while
first learning a text-based language. Graphical programming languages solve this
problem by allowing the user to drag and drop pieces of code together,
guaranteeing the correctness of grammar during the process. Some graphical
programming languages, such as the rewrite rules used in Klik & Play, are
designed for creating animations, which are useful in video games. However,
graphical languages are more suitable for simple programs since they take up
more memory. Creating a graphical language also require much more effort due
to its elaborate user interface.
Even though text-based and graphical programming languages have these
differences, they can also be easily mapped from one to the other. In fact, some
graphical languages, such as LogoBlocks (a graphical version of Logo) is first
translated into a text-based language (Logo), and then compiled/executed.
Ideally, GameWeaver should have both a text-based programming environment
and a graphical programming environment to satisfy the needs of children that
are both experienced and first-time programmers. But unfortunately, due to the
time limits on this project, the current version of GameWeaver only supports a
text-based programming environment. However, it is not difficult to implement
a graphical programming interface for this text-based language.
37
4.3.2 Compiled vs. Interpreted
In this section, we compare two types of languages, compiled and interpreted
(scripting) languages, which are executed differently in the development
environment. We first discuss the pros and cons of both languages in general,
and then explain why GameWeaver chose to use a compiled language.
In a compiled language, the source code is usually a high level textual language,
which is compiled into a binary executable file consisting of low-level binary code
(such as assembly). Programming languages such as C/C++ and Pascal are both
compiled languages. Traditionally, since C/C++ and Pascal compile to machine
specific binary code, they have been the languages of choice as far as speed and
efficiency have been concerned.
Interpreted (scripting) languages, on the other hand, can be run instantaneously
using an interpreter (scripting) engine, which parses textual information and
interprets it in real time. This provides a platform independent language but is
somewhat slower than a compiled language. Typical interpreted (scripting)
languages are Lisp, Logo, and JavaScript.
Recently Java has emerged as a compiled language that provides much of the
speed of traditional compiled languages but also provides the platform
independency of an interpreted (scripting) language. Though compiled, Java is
also interpreted using the Java Virtual Machine (JVM), a software engine that
interprets Java binary ‘class’ files, which contains code similar to an assembly
code. These binary codes (unlike assembly instructions) are portable to any
device, providing the device contains a JVM. This approach provides many of the
speed enhancements of assembly language while maintaining the portability of an
interpreted language.
38
In general, there are many advantages of compiled languages over scripting
languages. Programs written in compiled languages can run faster because parsing
does not need to take place at run time, and most compilers implement
optimizations to minimize the run-time of the binary executable file. A compiler
can detect syntax/parsing errors before run-time. To run a compiled program
outside the development environment, only the binary executable file needs to be
copied. Compiled languages can also hide the source code from users of a
program.
Scripting languages also have a number of advantages over compiled languages.
Scripting languages provide an interactive development environment where
pieces of a project can be tested before the entire program is complete. Programs
written in scripting language are easier to debug with the support of interactive
debugging environments.
GameWeaver uses a compiled language similar to Java, which compiles source
code to portable binary files. These binary files can be further executed on
different platforms (such as Palm Pilots and PocketPC™s) through platform
specific interpreters that act as “virtual machines”.
Traditionally, most programming languages for children, such as Logo, are
scripting languages because of the interactive development environment they
provide, but we chose a compiled/interpreted language for GameWeaver because
the games created here are intended to be played on various handheld devices,
which is a different environment than the one they are made in. To play a game
on a handheld device using a language that compiles to platform independent
binary code, we need to write an interpreter for executing the binary file for that
handheld device. On the other hand, using an interpreted language would force
us to write a version of the original scripting engine for the handheld device.
This requires the handheld device to use more memory and do significantly more
39
work than running an interpreter that executes binary files. Hence a compiled
language is a much better choice in our case, where our programs need to be
easily extendable to run on different platforms.
4.3.3 Detailed Specification
4.3.3.1 Data Types
There is only a single type of data abstraction in our language, integers. This
means all variables and constants are integers, and can be of no other type (such
as arrays, strings, and records). The advantage of restricting variables to a single
type is it simplifies the syntax of the language, and prevents kids from using
wrong types of variables, which is a common mistake that first-time programmers
often find frustrating to avoid. However, one may point out a draw back to this
approach by asking, “ what if they want to use more complicated data
structures?” The answer to this question is that a large class of arcade type
videogames can be made without more complicated data structures. The
simplicity gained is worth the limitation, which can be easily relaxed in future
versions if user studies suggest that we should. For our current purposes, it is
worthwhile to point out that, in practice, boolean types can be simulated using
numbers, and strings can also be displayed by explicitly drawing them in a
background.
4.3.3.2 Variables
Although all variables in GameWeaver are of integer types, they can still be
categorized into three groups based on their scope: global variables, local
variables, and temporary variables.
Global variables are shared across all characters in a game, meaning that any
character can read or change a global variable’s value. Since global variables are
sprite independent, they are declared in a separate “Edit Global Variables”
window accessible through the “Edit->Global Variables…” menu item. Global
40
variables can be accessed using the get_global stored procedure, and written
using the set_global stored procedure.
Local variables are sprite level variables similar to private member variables in
Java Classes. A character cannot access the local variables of any other character,
even if they are instances of the same sprite. Since local variables are sprite
specific, they are declared under the properties tab for each sprite, as shown in
Figure 17. Similar to global variables, local variables can be accessed through the
get_local and set_local stored procedures.
Temporary variables must be declared at the beginning of a procedure. They
have even smaller scopes than local variables. Their scope is only within the
procedure in which they are declared. To get the value of a temporary variable,
simply refer to its name, which is similar to how variables are referred to in C or
Java. But instead of using the = operator to assign values to temporary variables,
we designed a special set <variable name> <variable value>
statement, which is a much more intuitive way to assign variable.
All variable names need to be strings consisting of only letters and numbers.
Variables are automatically initialized to 0 once they are declared.
4.3.3.3 Operators and Expressions
As we have seen, a reference to a temporary variable is also a simple expression,
since it evaluates to the value of the variable. More complex expressions can be
created in GameWeaver using operators and parentheses.
There are two types of operators, arithmetic operators and logic operators.
Arithmetic operators include the binary operators +, -, *, /, and the unary
operator -. Logic operators include the binary operators <, >, <=, >=,
==, and !=. Since boolean is not a valid data type, the value of a boolean
41
expression (one that contains logic operators) is either 1 (if the expression is true)
or 0 (if the expression is false. For example, the value of the expression ((1 >
0) + 5) is 6.
4.3.3.4 Control Statements
There are two types of control statements in GameWeaver, if-statements and
while-statements, which is a bare minimum for making this language
functional. No additional control statements (such as repeat or switch)
were implemented because we wanted to keep the language simple, but could be
easily added if one so desires.
4.3.3.5 Procedures
For simplicity, the return type of procedures in GameWeaver is fixed to be a
number. (Technically, procedures should be called functions here since they all
have return values). As mentioned in section 4.2.2.1, there are two types of
procedures, ones kids create themselves (user-defined procedures), and ones built
into the system (stored procedures).
User-define procedures can contain any number of arguments and temporary
variables. The syntax for procedure declarations and calls are shown in Figure 19.
Procedure declarations can be in any order, even if they depend on each other.
For example, if procedure foo refers to procedure bar, foo does not have to
be declared after bar. Therefore, procedures can also be defined recursively.
Procedure declaration: to <procedure_name> (<arg1>, <arg2>, ..., <argn>) <temp_var1>, <temp_var2>, ..., <temp_varm> { <procedure_body> } Procedure call: <procedure_name>(<arg1>, <arg2>, ..., <argn>)
Figure 19: Syntax for procedure declarations and procedure calls
42
Stored procedures are called with the same syntax as user-defined procedures.
For a complete list of stored procedures and their definitions, please refer to
Appendix III.
On a side note, GameWeaver is a procedure-based language (similar to C and
Pascal) as apposed to an object-oriented language (such as Java and C++), for
two reasons. First, the level of abstraction that procedures provide is necessary
and sufficient for defining video games. An object-oriented language does not
have any clear advantage over a procedure-based language while the programs
written are simple arcade-type video games. Second, even though object-oriented
programming is a nice programming concept to know about, it might be too
abstract a concept for children to learn.
This concludes this section on the programming language. A more technical
definition of this language expressed using a CFG (Context Free Grammar) is
given in Appendix II.
43
C h a p t e r 5
IMPLEMENTATION
5.1 Overall System
The fact that GameWeaver uses a compiled rather than an interpreted/scripting
language suggests an overall system consisting of two parts, a PC-based integrated
development environment (IDE) for creating games, and platform dependent
interpreters for running games on handheld devices, as shown in the following
figure. Games are developed in the IDE, and played on any of the interpreters.
Interpreter Compiler
Gameboy Interpreter
Palm Interpreter
PocketPC Interpreter
IDE
user’s program
binary executable
GUI
PC Handheld Devices
(need to do) (need to do)
Figure 20: Overall system design involving a platform independent IDE and interpreters for individual handheld devices
44
The IDE provides an environment for users to design, implement, run, and
debug their game projects. A user creates a project by first using the graphical
tools provided by the IDE to define the appearance of their characters in the
game, and then writing programs to specify the desired behaviors of these
characters. The IDE contains a compiler that compiles user source code into
binary executable code, which can be run using the interpreter included in the
IDE, so kids can test out their games within the development environment.
After a user is satisfied with how his/her game looks and runs in the IDE, he/she
can play the game on a handheld device by simply exporting the executable byte-
code to the byte-code interpreter for that handheld device.
The advantage of such a design is the “write once, run everywhere” philosophy.
A user only needs to write a game once (in the IDE), for it to run on any
handheld device that has an interpreter implemented for it. All of these
interpreters need to implement a common interface, the specification of which is
given in section 5.2.3.
To show that such a system design works, we have successfully implemented the
IDE, and the interpreter for Palm devices, the details of which are given in
following two sections.
5.2 IDE (Integrated Development Environment)
The IDE is implemented entirely in Java (as apposed to C/C++) for three
reasons. First, contrary to C/C++, Java is platform independent, which allows
the same program to run on any operating system. Second, programming in Java
is more efficient since it has a larger library of built-in functions. Third, the
development cycle was going to be shorter in Java because of personal preference
and familiarity with it. Of course, as an interpreted language, Java has the
45
disadvantage of running slower than C++, but hopefully this difference in
performance should not be noticeable if the IDE is implemented optimally and
the games being implemented are not too complicated. Further more, what
matters more is not how well the games perform in the IDE, but on the
handheld devices.
The implementation of the IDE consists of four parts, the GUI (graphical user
interface), the game objects layer, the compiler, and an interpreter for running
games within the IDE. Figure 21 illustrates the data flow between these
components.
GUI
Game Objects
Compiler
Interpreter
read/write
load/save
source code
byte code
graphical information
project fi le
.gwe file
Figure 21: Block diagram representation of the four main components of the IDE
The following sections explain the implementation of each of these components
in greater detail.
5.2.1 GUI
The GUI (Graphical User Interface) for the IDE consists of several different
windows allowing users to edit and view components for their game projects.
Many of these windows were presented in Chapter 4.
46
The entire GUI is implemented using swing components provided by Java, most
of which is rather straightforward.
5.2.2 Game Objects Layer
The game objects layer is a collection of classes encapsulating the data necessary
for representing a game project. These classes correspond to the game objects
(Sprites, Shapes, Tiles, and Backgrounds) described in the previous chapter.
The game objects layer serves two purposes. First, it provides a level of
abstraction to allow communication between the GUI and the
compiler/interpreter. Second, it makes sure that projects can be persistent.
Abstraction is rather straightforward to implement, but persistence is a bit tricky.
In the context of this thesis, persistence involves saving/loading of projects and
exporting/importing components of a project (such as Tiles). Java automatically
handles persistence of objects through the Serializable interface, therefore a
simple solution is to have all game objects implement Serializable, and use
standard library functions to save/load these objects.
This method of implementing persistence doesn’t quite work due to the
hierarchic structure of game objects. For example, since Shapes consist of Tiles,
Tile objects exist both independently as game objects and as a component of
Shape. Therefore when a project is being saved (serialized), the Tile objects
contained in any Shape are saved at least twice, once as a component of the
Shape, and once as just Shapes in the project. When the project is loaded back
again, these Tiles are not only loaded more than once, but each load creates a
separate instance of the Tile, and unlike the original project, there is no link at all
between these separate instances of the same Tile in the loaded project.
Therefore another method of persistence is required.
47
To solve the persistence problem, GameWeaver chose a popular method used
for many professional IDE’s (such as CodeWarrior) to specify GUI components.
The method simply assigns a unique ID (UID) to every game object. This UID
is not only unique within a single game object category (such as Sprite), but also
unique across different types of objects (Sprites, Shapes, etc). This allows objects
to be referenced using UID rather than the object itself, and whether two objects
are instances of the same object can be easily determined through comparing
UIDs.
Another advantage of using UIDs is that they allow game objects to be easily
represented in byte code. An alternative for identifying objects is to use object
names as apposed to UIDs, which are also unique across the system, but in order
to represent these objects in byte code, the strings need to be converted into
numbers, which are essentially UIDs. Therefore, GameWeaver uses object
names to identify objects at the user level (since it is more intuitive), and UIDs to
represent objects internally.
5.2.3 Interpreter
After seeing how the game objects layer encapsulates information about a game
in a structured way, we then look at the interpreter, which is the component of
the IDE that uses this information to execute the game. We will first explain the
format of byte codes used in GameWeaver, and then discuss the implementation
of the interpreter for the IDE. Last but not least, we will give the specifications
for creating additional interpreters used for executing games outside the IDE
(such as ones for handheld devices).
5.2.3.1 Byte Codes
Similar to byte codes in other compiled/interpreted languages, byte codes in
GameWeaver are numeric values representing commands that can be directly
executed by the byte-code interpreter. Most byte codes operate on numbers that
48
are stored on a stack (provided by the interpreter). For example, the PLUS byte
code pops two numbers from the top of the stack, and pushes the sum back onto
the stack. GameWeaver uses a total of 70 byte codes. They can roughly be
categorized into five categories, as shown in Table 2. For a detailed definition of
all byte codes, refer to Appendix I.
Category Example Operator PLUS, LESS_THAN Display Control GET_TILE_AT,
SET_BACKGROUND Data Access GET_X, SET_HEADING,
SET_GLOBAL System GET_STACK_POINTER,
SET_FRAME_POINTER Program Flow Control JUMP, GOTO Special FD, COLLIDES_TILE
Table 2: Byte code categories
These byte codes were designed so the most common tasks (such as moving
forward or detecting collisions) that users would like their game characters to
perform can be implemented using very few code words, which both simplifies
the task of programming and improves the runtime performance.
5.2.3.2 Interpreter Implementation for IDE
The interpreter for the IDE is used for executing games within the IDE, so kids
can test and debug their games within the development environment.
The interpreter’s main functionality is to simulate a multithreaded runtime
environment using a single thread. As discussed in the previous chapter, users
expect all runtime characters to appear to be running simultaneously, implying
each runtime character is running in its own thread. The interpreter simulates
such a runtime environment by sequentially executing the run procedure of each
runtime character (some might be executed more frequently than other
49
depending of the speed of the character). Since we assume the time required for
executing these run procedures is negligible, the user would not be able to tell
that everything is run using just a single thread.
As shown in Figure 22, the detailed implementation of the interpreter consists of
a runtime instance of the observer sprite, and a variable number of runtime
characters. The switching of tasks between the observer and these other runtime
characters is controlled using the EXECUTE and STOP byte codes. Each
runtime character has its own copy of a stack (used for temporary storage by byte
codes), and local variables. In addition, non-observer characters have attributes
such as x position, y position, heading, speed, and shape. The interpreter also
provides space for storing global variables and the state of the background, which
is also used (together with the position and shape of runtime characters) for
calculating and updating the display image.
...
stack
observer (runtime)
local vars
...
stack
pacman
local vars
x, y heading speed shape ...
stack
ghost1
local vars
x, y heading speed shape ...
stack
ghost2
local vars
x, y heading speed shape
... ...
Runtime characters:
EXECUTE
STOP
global variables, background
Figure 22: Block diagram of interpreter implementation
5.2.3.3 Interpreter Implementation for Handheld Devices
Compared to the interpreter for the IDE described above, external interpreters
for handheld devices have the additional task of reconstructing game data from
50
GWE (GameWeaver executable) files. This is not a difficult task given the
specifications of the format of GWE files (see Appendix IV). Once game data is
reconstructed, the implementation for the rest of such interpreters are exactly the
same as the interpreter in the IDE, except they will most likely be implemented in
a device specific language other than Java
5.2.4 Compiler
After understanding how the interpreter is implemented to execute byte codes,
this section discusses the compiler, which is in charge of converting source code
to executable byte code, and also generating the GWE file encapsulating all
executable information about a game. This section first illustrates how the
conversion of source to byte code is implemented, and then briefly goes over the
design of the GWE executable file.
5.2.4.1 From Source Code to Byte Code
The compiling process can be broken into three stages, the parser, the code
generator, and the optimizer, as shown in Figure 23. The parser creates a parse
tree from source code, while the code generator generates byte code directly from
the parse tree, and the optimizer performs optimizations on the byte code for
runtime improvement.
Parser Code Generator
Optimizer source code
parse tree
byte code
byte code
Figure 23: Compiler Implementation represented in three stages
The following sections discuss each stage in more detail.
51
• Parser
The implementation of a parser can be a very complicated task, but luckily there
are many existing tools that generate parsers from grammar specifications.
GameWeaver uses two such tools, JLex (for lexical analysis) and Java Cup (for
actual parsing).
Yylex.java
parser.java
Yylex
parser.cup
JLex
Cup
source code
symbols
parse tree
Figure 24: Parser implementation using JLex and Java Cup
JLex is a lexical analyzer generator written for Java by Elliot Berk of Princeton
University. JLex uses a lexical specification (Yylex) to produce a Java program
(Yylex.java), which is further used for converting source code to a list of
predefined symbols. These symbols include operators, reserved words, delimiters,
and literals (see Appendix V for a complete list of symbols used in
GameWeaver). Similarly, Cup is an LALR parser generator written for Java by
Scott Hudson of Princeton University. Cup converts a grammar specification file
(parser.cup) to a Java program (parser.java), which can be used to turn the one-
dimensional list symbols outputted by the lexical analyzer into a two-dimensional
parse tree. Therefore, JLex and Cup simplifies the task of programming parsers in
Java to writing the specification files Yylex and parser.cup.
52
The parse tree generated here is similar to a parse tree for languages such as C
and Pascal. The creation rules for the parse tree are defined using embedded Java
code in parser.cup. These rules operate on additional classes we created for
defining the data structure of parse trees. These classes include an abstract class
(TreeNode) and more specific classes (such as TreeIf and ExprBinary) that
extends it, some of which implements the Expression interface, meaning they
represent expressions that can be evaluated to a number at run time (such as
ExprBinary). These classes recursively define themselves and each other (see
Appendix VI for a complete list of definitions of TreeNodes). Figure 25 shows
an example of a parse tree.
TreeIf
ExprBinary
TreeBlock
Operator >
ExprNum 0
ExprId x
CallExpr
ExprId fd
ExprBinary
ExprId x
Operator +
ExprNum 1
Figure 25: Parse tree corresponding to source code: "if (x>0) { fd(x+1) }"
• Code Generator
The parse tree created by the parser is directly fed into the code generator to
generate byte code. This is unlike most other compilers, which perform semantic
checks and create intermediate block codes before code generation. These two
53
additional compiling stages can be omitted in this project due to the simplicity of
the language.
The process of converting a parse tree to a series of byte codes is usually called
flattenizing. Flattenizing is a recursive process. To flattenize a parse tree, we
recursively flattenize its child trees first, and then combine the results (possibly
with some additional byte codes depending on what type of parse tree it is) to
form the byte codes for the original tree. Next we describe the details of how
parse trees representing binary expressions, if-else control statements, and
procedure calls are each flattenized.
Binary expressions are flattenized by simply rewriting the expression in reverse
polish notation. As shown in Figure 26 we assume the binary expression being
flattenized is of the form “<expr1> <op> <expr2>” where <expr1> and
<expr2> are themselves expressions and <op> is an Operator (such as + or -).
We use [expr1] and [expr2] represent the results of flattenizing <expr1> and
<expr2>, while [op] is the byte code for <op>. Figure 26 also shows the
flattenized results of a simple binary expression containing another binary
expression.
Rule : <e xp r1> <op> <e xp r2> ⇒ [e xp r1] [expr2] [op] Exa mp le : 3*(1+2) Exp rBina ry
3 *
Exp rBina ry
1 + 2
⇒
NUM8 3 NUM8 1 NUM8 2 PLUS MULT
[expr1]
[e xpr2]
[op] Figure 26:Example of flattenizing a binary expression
Control flow type parse trees such as if-then, if-then-else, and while
parse trees are a little more complicated to flattenize since the program flow is
54
controlled by the value of a condition expression. Figure 27 demonstrates how an
if-then-else tree is flattenized using two additional byte codes IF_ELSE
and JUMP. Again, assume <cond>, <thenb.lock> and <elseblock> are sub-
trees than can be flattenized into the byte codes [cond], [thenblock] [elseblock] by
recursion. The flattenized byte code for an if-then-else tree operates as
follows. First executing [cond] evaluates and pushes the value of the conditional
expression (call this number x) on the stack, and [sizeof[thenblock]+2] pushes the
number of byte codes in [thenblock] plus 2 (call this number y) onto the stack. If
x is greater than 0, IF_ELSE does not do anything, hence the program proceeds
to executing [thenblock], and the consecutive JUMP skips over [elseblock].
However if x no greater than 0, then by definition, IF_ELSE increases the
program counter by y, and executes [elseblock], as desired.
Rule: if (<cond>) { <thenblock> } else { <elseblock> } ⇒ [cond] [sizeof[thenblock]+2] IF_ELSE [thenblock] [sizeof[elseblock]] JUMP [elseblock] Example: if (1>0) { stop() } else { execute() } TreeIf
ExprBinary
Operator >
EzprNum 1
EzprNum 0
CallExpr stop
CallExpr execute
⇒
NUM8 1 NUM8 0 GREATER_THAN3 IF_ELSE STOP 1 JUMP EXECUTE
Figure 27: Example of flattenizing an if-then-else statement
Call expressions are used to represent procedure calls. As described in the
previous chapter, there are two types of procedures in GameWeaver, stored
procedures and user-defined procedures. Even though the syntax for calling
these two types of procedures is the same, the procedure calls are flattenized
differently.
55
User-defined procedures use a standard jump to subroutine protocol. In this
protocol, the caller pushes arguments and the old frame pointer on the stack, and
allocates space for local variables and the return value, and jumps to the target
address of the procedure being called, at which point the caller takes over control.
After the caller is done executing, it places the calculated return value on the
stack, restores the frame pointer, and jumps back to the caller. Table 3 shows the
state of the stack when a user-defined procedure is being called.
…
<return value>
<arg n>
<arg n-1>
…
<arg 1>
<frame pointer>
<local variable 1>
<local variable 2>
…
<local variable m>
<target address>
JTS
… Table 3: Stack configuration during calls to user-defined procedures
Stored procedures (which are defined by the system) use a different type of
protocol. Instead of jumping to a subroutine, calls to stored procedures are
simply replaced using the byte codes that define them. Appendix III is a list of all
the stored procedures and their byte code definitions. Of course, we could have
also used the jump to subroutine protocol for stored procedures, but the byte
56
code produced in this protocol runs faster since there aren’t any jumping
overheads. However, the size of the compiled code is larger in this case because
the same instance of code is being duplicated everywhere, but fortunately most
stored procedures consist of only a couple of byte codes, hence size should not
be a significant issue. On a side note, the reverse is not true; i.e., we can’t use this
protocol for user-defined procedures for the simple fact that recursive function
calls would be impossible to flattenize.
One more detail to explain is how user-defined procedures are linked, i.e. how
the caller figures out where the compiled procedure is stored so it can generate
the byte codes for jumping to that target address, at which time the procedure
might have not even been compiled. We solve this problem by substituting all
these target addresses with special markers identifying which procedure it is trying
to jump to. And after all procedures have been compiled, we replace these
markers with the actual addresses.
• Optimizer
The current version of the optimizer operates by removing “useless” byte codes
from the output of the code generator, decreasing the size of the executable code
and also improving the runtime performance. More specifically, it removes all
occurrences of byte codes of the form “NUMBER <x> NUMBER 1 POP”,
which translates to pushing a number <x> on the stack and immediately popping
it, which is “useless” since it is equivalent to doing nothing. This particular type
of “useless” code occurs very frequently in the generated byte code (almost every
time a stored procedure is called). Therefore it can decrease the size of the
executable by quite a significant amount.
57
5.2.5 GWE (GameWeaver Executable) file
As mentioned earlier, games created using GameWeaver’s IDE can be exported
in the form of GWE (GameWeaver Executable) binary files. These GWE files
can be executed using the interpreters running on handheld devices.
GWE files need to contain the minimum information necessary for an interpreter
to run a game, which includes the definition for all the graphical objects (Tiles,
Shapes, Backgrounds) and all the Sprites including the Observer. Note that for
all objects, we only need to store their UIDs (not their names) in the GWE file
because all objects are internally referenced using UIDs. For Sprites, only
compiled binary code need to be stored (instead of the original source code).
On a side note, the color data in the graphical objects is saved as 16 bit colors, (1
spare bit, 5 bits red, 5 bits green, 5 bits blue) giving 32768 colors and potential for
transparency using the spare bit.
The detailed format of GWE files is given in Appendix IV.
5.3 A Sample Byte-Code Interpreter: Game Interpreter for the Palm
Platform
This section describes an implementation for running GameWeaver games on
Palm devices. As shown in Figure 28, the solution consists of two programs:
GameWeaver.prc and GameCond.dll. GameWeaver.prc is a palm application
allowing users to play any games stored in the application’s database, which can
be updated during a HotSync operation through the GameCond.dll conduit.
58
GameWeaver.prc (palm application)
Database:
pacman
tetris
…
Palm PC
read
write
GameCond (conduit)
Directory: pacman.gwe tetris.gwe …
Figure 28: Palm implementation block diagram
5.3.1 Palm Application: GameWeaver.prc
When GameWeaver is run on the palm, it first displays a list of all the games that
are available in the application’s database. After the user chooses a game, it starts
the execution of the game (Figure 29 is an example of Pacman played on the
palm). While a game is running, the bottom 6 hardware buttons on the palm are
mapped to the virtual arrow keys and “a”, “b” buttons. The only way to stop a
game while it is running is by tapping the “exit game” button at the bottom of the
screen.
59
Figure 29: Pacman played on Palm (emulator)
60
GameWeaver.prc is implemented in C++ using CodeWarrior for Palm OS since
it is the only professional IDE for developing palm application. The code is
nicely isolated into two separate parts that are device dependent and independent.
Device dependent code consists mostly of user interface features such as
displaying images and detecting user input events, while the essential part of the
interpreter is all device independent, meaning it uses standard C/C++ libraries.
The main advantage of having a significant part of the interpreter implemented in
device independent code is expandability. Device independent code can be
reused for creating interpreters for other platforms that also support C/C++.
For example, to create an interpreter on the Windows CE OS for PocketPCs, we
only need to rewrite the device dependent user interface code, which is much less
work than rewriting the entire interpreter.
All palm applications require a unique four digit ID. GameWeaver’s ID is
“gWEp”. On a side note, GameWeaver.prc only runs on Palm OS 3.5 or higher.
This is because we used certain bitmap functionalities that are only supported by
OS 3.5 and higher.
Before discussing the conduit application, let us first take a look at how games are
stored on the Palm OS. Palm supports databases for storing information, which
is similar to the file system in Windows. Palm applications have read/write
accesses to records in databases associated with them. In our case, GameWeaver
only reads from the single database associated with it (called gweDB). Games are
represented as records in this database. Palm OS limits the size of database
records to be of size no greater than 64KB, which means our .gwe file can be of
no greater than 64K as well. A way to work around this problem is to use
multiple records in the database to store a game, but there is no immediate need
to put this fix in yet since most arcade type games don’t seem to need more than
61
64K. For example, the compiled version of a Tetris game is only 7K, and the
Pacman game 2K.
5.3.2 Conduit: GameCond.dll
The only way to load data to/from palm devices is through conduits. Conduits
are dynamically linked libraries in C. They provide a mean of data
communication between the palm and the desktop. GameCond.dll is a conduit
we wrote for loading games onto the Palm devices.
Similar to all other conduits, in order to use GameCond, we need to register it
with the HotSync Manager first, so that GameCond automatically gets called
during a HotSync operation. We can manually register a conduit by using the
Conduit Configuration application (CondCfg.exe) that comes with CodeWarrior’s
Conduit Development Kit to configure settings for GameCond as shown in
Figure 30 and Figure 31. There is also an alternative way of automatically
registering conduits without using CondCfg, but it is more complicated to
implement.
62
Figure 30: Conduit Configuration Window
63
Figure 31: Conduit configuration settings for GameCond
After successfully registering the GameCond conduit, it gets called by the
HotSync Manager during each HotSync operation. When this happens,
GameCond first erases all the games that are currently inside GameWeaver’s
application database on the palm, and then copies all .gwe files in a fixed directory
on the desktop to the database on the palm as database records. This directory
(called GameWeaver) is created automatically when the palm application
GameWeaver is first installed, and shares that same path as all the other palm
applications. Therefore to install/erase a game on the palm, one only needs to
copy/delete the corresponding .gwe file into/from the GameWeaver directory on
64
the desktop, and it will automatically get installed/erased during the next HotSync
operation.
65
C h a p t e r 6
CONCLUSION
This thesis has described a video-game construction kit, called GameWeaver,
which includes a programming language and an integrated development
environment specifically designed for children to create games for handheld
devices. The current version of GameWeaver allows children to create games on
desktops and play them on Palm compatible devices.
While these achievements show that it is possible to provide children with a
powerful yet easy-to-use toolkit for making games for a handheld device, there is
much potential for further developments. First, we would like games created in
GameWeaver to run on not just Palm Pilots, but PocketPC™ machines and
Color Gameboys™ as well. As discussed in the previous two chapters, this
involves implementing byte-code interpreters for each of these platforms.
Examining the implementation of the byte-code interpreter for the Palm Pilot in
detail shows that this should not be a difficult task.
Second, as stated earlier in Chapter 2, the physical expandability of handheld
devices increases their attractiveness as gaming devices. Hence we can add an
entire new dimension to the game design space by enabling children to use
GameWeaver to attach hardware add-ons to their games, allowing virtual game
characters to interact with the physical world. We have often heard children say
that they would like to design their own games in which the characters or the
background environment are influenced by changes in the external world (e.g. if
the handheld is shaken or tilted by the child playing the game or if the child is
excited), or the external world is affected by what happens in the game (e.g. the
child playing the game would feel a vibration, achieved by turning on a motor
66
carefully mounted on the handheld, every time their character bounces from an
obstacles.)
Third, the current version of GameWeaver can only be used to create single-
player games. We did consider the possibilities of creating multi-player games, but
temporarily dismissed this idea due to both time limitations and the
complications multi-player games introduce. It would be a challenging but
worthwhile project to extend/modify GameWeaver to support multi-player
games by using multi-device communication capabilities of handheld devices,
which would undoubtedly expand the space of possible games and interactions
greatly.
Last but not least, a very important task remaining is to distribute GameWeaver
to kids for actual use not only to measure our project’s success, but also to learn
what needs to be re-examined in future versions of the GameWeaver. We are
inspired and driven by the promise of the range of creative and learning-rich
activities that videogame construction brings to children and are pursuing all
these research and development opportunities actively.
67
APPENDIX I: BYTE CODES
Name Byte code
Behavior
GET_TILE_AT 0 Pop <x>, then <y>; push the UID of the tile at position in (<x>, <y>) in the current background
SET_TILE_AT 1 Pop <x>, <y>, and <tileid>; set the tile at position (<x>, <y>) to be the tile with UID <tileid>
NUMBER8 2 Push the numeric value of the following byte code onto the stack
NUMBER32 3 Push the numeric value of the next four byte codes (32-bit integer) onto the stack
COLLIDES_TILE 4 Pop <y>, then <x>; push them back on the stack, push 1 if the current character collides with the tile at (<x>, <y>) in current background
COLLIDES_CHAR 5 Pop <y>, then <x>; push them back on the stack, push 1 if the current character collides with the character (if any) at (<x>, <y>), otherwise push 0
GOTO 6 Pop <loc>; set program counter to <loc>
IF_ELSE 7 Pop <delta>, pop <cond>; if <cond> is equal to 0, increment program counter by <delta>
JUMP 8 Pop <delta>; increment program counter by <delta>
SET_XY 10 Pop <y>, pop <x>; sets the current character at position (<x>, <y>)
GET_X 12 Push x position of current character on the stack
GET_Y 13 Push y position of current character on the stack
GET_HEADING 14 Push the heading of current character on the stack
PLUS 15 Pop <b>, then <a>; push <a>+<b>
68
MINUS 16 Pop <b>, then <a>; push <a>-<b> LESS_THAN 17 Pop <b>, then <a>; push 1 if <a>
less than <b>, otherwise push 0 GREATER_THAN 18 Pop <b>, then <a>; push 1 if <a>
greater than <b>, otherwise push 0 EQUALS 19 Pop <b>, then <a>; push 1 if they
are equal, otherwise push 0 SET_HEADING 21 Pop <heading>; set heading of
current character to <heading> RANDOM 22 Pop <n>; push a random integer
between 0 and <n>-1 onto stack GET_FRAME_POINTER 23 Push current frame pointer on the
stack SET_FRAME_POINTER 24 Pop <fp>; Set current frame pointer
to be <fp> AND 25 Pop <a>, then <b>; push 1 if both
<a> and <b> are greater than 0, otherwise push 0
OR 26 Pop <a>, then <b>; push 1 if either <a> or <b> is greater than 0, otherwise push 0
NOT 27 Pop <a>; push 0 if <a> is greater than 0, otherwise push 1
POP 28 Pop <n>, then pop the next <n> numbers from the stack
LESS_THAN_OR_EQ 29 Pop <b>, then <a>; push 1 if <a> is less than or equal to <b>, otherwise push 0
GREATER_THAN_OR_EQ 30 Pop <b>, then <a>; push 1 if <a> is greater than or equal to <b>, otherwise push 0
GET_PROGRAM_COUNTER 31 Push the value of the program counter on the stack
GET_STACK_POINTER 32 Push the value of the stack pointer on the stack
GET_STACK_AT 33 Pop <location>; Push the value of the stack at <location>
MUL 34 Pop <b>, then <a>; push <a>*<b> DIV 35 Pop <b>, then <a>; push <a>
divided by <b> (truncates remainder)MOD 36 Pop <b>, then <a>; push the
remainder of <a>/<b>
69
SET_NUMBER_AT 37 Pop <location>, pop <value>; Set the value of the stack at <location to be <value>
CREATE_CHARACTER 38 Pop <type> <x>, <y>, <heading>, <speed>; creates a runtime character of the sprite type <type>, with initial position (<x>, <y>), heading <heading>, and speed <speed>
GET_STACK_RELATIVE_AT 39 Pop <delta>; push the value of the stack at the current stack pointer plus <delta>
GET_HEADING_DX 40 Pop <heading>; push either 1, 0, or –1 according to the xcor direction of <heading>
GET_HEADING_DY 41 Pop <heading>; push either 1, 0, or –1 according to the ycor direction of <heading>
EXECUTE 42 Switches from executing the observer to executing all other characters
STORE_REG_A 43 Pop <value>; set register to <value> GET_REG_A 44 Push the value of the register onto
stack STOP 45 Destroys all runtime characters and
resumes executing the observer SET_VARIABLE 46 Pop <var_index>, pop <value>; sets
the number at position frame pointer + <var_index> on the stack to be <value>
NUMBER_OF 47 Pop <sprite_uid>; push the number of runtime characters of sprite type <sprite_uid>
SET_BACKGROUND 48 Pop <bg_uid>; set the current background to background <bg_uid>
PRINT 49 Pop <number>; Prints <number> JTS (jump to subroutine) 50 Pop <loc>; push current program
counter to stack, set program counter to <loc>
RTS (return to subroutine) 51 Pop <loc>; set program counter to <loc>
COLLIDES_TILE_AT 52 Pop <y>, then <x>; push 1 if the current character collides with the tile at (<x>, <y>) in current background
70
SET_GLOBAL 53 Pop <index>, pop <value>; set the value of global variable with index <index> to <value>
GET_GLOBAL 54 Pop <index>; push the value of global variable with index <index>
SET_SHAPE 55 Pop <shape_uid>; Attempts to set the shape of current character to <shape_uid>, push 1 if succeeded, 0 otherwise
GET_SHAPE 56 Push the uid of the current character’s shape to the stack
DIE 57 Kills the current character SET_LOCAL 58 Pop <index>, pop <value>; set the
value of the local variable with index <index> to <value>
GET_LOCAL 59 Pop <index>; push the value of local variable with index <index> to stack
GET_TILE_OF_SHAPE_AT 60 Pop <shapeId>, <x>, and <y>; push 0 if position (<x>, <y>) of shape with UID <shapeId> is empty, otherwise push the UID of the tile at position (<x>,<y>) of the shape with UID <shapeID>
PAUSE 61 Pop <t>; Pause the entire game for <t>/10 seconds
GET_VISIBLE 62 Push 1 if current character is visible, 0 otherwise
SET_VISIBLE 63 Pop <visible>; set current character to be visible if <visible> is greater than 0, to be invisible otherwise
SET_SCORE 64 Pop <score>; set the score to be displayed to be <score>
GET_SCORE 65 Push the score being displayed SET_SCORE_VISIBLE 66 Pop <visible>; set score to be visible
if <visible> is greater than 0, to invisible otherwise
GET_SCORE_VISIBLE 67 Push 1 if score is visible, 0 otherwise NOP 100 A helper byte code that does not
perform any operation END_TREE_BLOCK 101 Same as above
71
APPENDIX II: GRAMMAR
Meta-notation: <foo> means foo is a nonterminal. foo (in bold font) means that foo is a terminal [x] means zero or one occurrence of x x* means zero or more occurrences or x x+, a comma-seperated list of one or more x's | seperates alternatives ------------------- <procedure> -> to <id> ( [<id>+,] ) [<id>+,] <block> <block> -> { <statement>* } <statement> -> <method_call> | if ( <expr> ) <block> [ else <block>] | while ( <expr> ) <block> | return [<expr>] | set <id> <expr> | <block> <method_call>-> <id>([<expr>+,]) <expr> -> <id> | <method_call> | <literal> | <expr><bin_op><expr> | -<expr> | (<expr>) <bin_op> -> + | - | * | / | < | > | <= | >= | == | != | && | || <literal> -> [-]<digit><digit>* <digit> -> 0|1|2|3|4|5|6|7|8|9 <id> -> <alpha><alpha>* <alpha> -> a|b|c|.....|z|A|B|C|....|Z
72
APPENDIX III: STORED PROCEDURES
Procedure Definition set_heading(<heading>) Sets the heading of current character to
<heading>, returns 0 get_heading() Returns the heading of current character rt(<degree>) Rotates the heading by <degree>*45 degrees
clock-wise, returns 0 lt(<degree>) Rotates the heading by <degree>*45 degrees
counter-clock-wise, returns 0 get_x() Returns the x position of current character get_y() Returns the y position of current character set_xy(<x>, <y>) Attempts to set the position of current
character to <x>,<y>, returns 1 if successful, 0 otherwise (due to collisions)
fd(<number>) Attempts to move current character forward <number> steps, returns 1 if successful, 0 otherwice (due to collisions)
get_speed() Returns the speed of current character set_speed(<speed>) Sets the speed of current character to
<speed>, returns 0 create(<sprite>, <x>, <y>, <heading>, <speed>)
Creates an instance of <sprite>, initializing it’s x, y positions, heading, and speed variables to <x>, <y>, <heading> and <speed> accordingly, returns 0
execute() Tells all existing characters to start running, returns 0 (can only be called by observer)
stop() Deletes all existing characters except the observer, and resumes execution from where the last “execute” procedure was called in the observer, returns 0
die() Kills the current character Pause(<time>) Pauses the entire game for <time>/10
seconds set_tile_at(<x>, <y>, <tile>)
Sets the background tile at position <x>,<y> to be <tile>, returns 0
set_background(<background>)
Sets the entire background to be <background>, returns 0
get_shape() Returns the shape of current character set_shape(<shape>) Sets the shape of current character to
73
<shape>, returns 0 get_global(<varname>) Returns the value of the global variable
<varname> set_global(<varname>, <value>)
Sets the value of the global variable <varname> to <value>, returns 0
get_local(<varname>) Returns the value of the local variable <varname>
set_local(<varname>, <value>)
Sets the value of the local variable <varname> to <value>, returns 0
get_visible() Returns 1 if the current character is visible, 0 otherwise
set_visible(<visible>) Sets the current character to be visible if <visible> is 1, and invisible if otherwise, returns 0
random(<max>) Returns a random number between 0 and (<max>-1)
set_score(<score>) Sets current score to <score>, returns 0 get_score() Returns the current score set_score_visible(<visible>) Sets the score to be visible if <visible> is 1,
and invisible if otherwise, returns 0 get_score_visible() Returns 1 if the score is currently visible, 0
otherwise get_tile_of_shape_at(<shape>, <x>, <y>)
Returns the UID of the tile at position (<x>, <y>) in <shape>
number_of(<sprite>) Returns the number of <sprite> characters in the game
print(<num>) Displays <num> in a dialog box, returns 0 (used for debugging)
74
APPENDIX IV: GWE FILE FORMAT
The GWE (GameWeaver Executable) file format stores game objects (Tiles, Shapes, Backgrounds, Sprites and the Observer) sequentially, consisting of records. Each record contains a header and data section. The header is the same format among all objects. It also contains information identifying the type of data(object) contained in the data section. The First record in the file is the GWE File header, it contains general information about the file. Size (Bytes)
Data Type Description
12 Char[10] Always “GAMEWEAVER01”, just used to recognize the start of the file
4 int The Number of Tiles in the File 4 Int The Number of Shapes in the File 4 Int The Number of Backgrounds in the File 4 Int The Number of Sprites in the File 4 Int Total Number of Objects in File (Inc
Observer) = Sprites + Tiles + Backgrounds + Shapes
4 int Number of Global Variables All Objects have the following Header Format Size (Bytes)
Data Type Description
4 int The length of the data (including this element) This can be used to skip this entire record if it isn’t recognized
4 Int Object Identifier (UID) 4 Int Object type identifier
0 = Error 1 = Tile 2 = Shape 3 = Background 4 = Sprite 5 = Observer
4 Reserved
75
Tile Format Size (Bytes)
Data Type Description (has Tile as Object Type)
16 HEADER AS ABOVE 128 WORD[8][8]
(128 bytes long)
16 bpp Pixeldata reading reading left to right, top to bottom. In RGB format 1 bit unused 5 bits red, 5 bits green, 5 bits blue
Shape Format Size (Bytes)
Data Type Description (has Shape as Object Type)
16 HEADER AS ABOVE 16-80 UID[4][4] Tile Grid, consisting of Tile
Identifiers, read left to right, top to bottom
Background Format Size (Bytes)
Data Type Description(has Background as Object Type)
16 HEADER AS ABOVE 20 x 18 x 4
UID[20][18] Tile Grid, consisting of Tile Identifiers, left to right, top to bottom
Eventhandler Format Size (Bytes)
Data Type Description
4 Int ByteCode Offset 4 Int Event Id 4 Int L – length of Parameter list 4 x L Int[L] List of EventHandlerParameters
This is Different for every Handler Sprite Format Size Bytes
Data Type Description
16 HEADER AS ABOVE (has Sprite as Object Type)
4 UID Shapes 4 Int Number Of Local Varibles
76
4 Int T - Length of Colliding Tile List 4 x T UID[T] List of Colliding Tiles 4 Int S - Length of Colliding Shapes
List 4 x S UID[S] List of Colliding Shapes 4 Int Length of ByteCode BCL Byte[BCL] Byte Code 4 Int EH – Number Of EventHandler
Objects ?? EVENTHANDLERS[EH] List of Even Handlers objects The Observer format is also the same as the Sprite, with the Exception that the Object Type is Observer and the List of Event Handlers is Empty.
77
APPENDIX V: SYMBOLS USED IN PARSER
IMPLEMENTATION
Symbol Name Value SUB_OP - ADD_OP + MUL_OP * DIV_OP / MOD_OP % AND_OP && OR_OP || EQ_OP == NEQ_OP != LESS_OP < GREATER_OP > LESSEQ_OP <= GREATEREQ_OP >= IF If ELSE Else WHILE While LBRACE { RBRACE } LPAREN ( RPAREN ) RETURN Return COMMA , NUMBER any number (3, 5, 1000000) SET Set TO To ID Any string consisting of only letters and number (must
start with a letter) that is not already the value of a symbol, e.g. “pacman”, “maze1”
78
APPENDIX VI: LIST OF TREE NODES
The following is a list of the different type of tree nodes used in the parse trees
generated during compilation.
Node Type Representation CallExpr A procedure call ExprBinary A binary expression ExprId A simple expression consisting of a single variable ExprNum A simple expression consisting of a single number ExprUni A negated expression Operator A binary operator Procedure A procedure definition ReturnInstr A return instruction TreeIf An if statement TreeSet A set instruction TreeWhile A while statement
79
APPENDIX VII: PONG (BREAKAWAY)
The following is an example of how a simple version of the game Pong
(Breakaway) can be implemented in GameWeaver, as shown in the following
figure.
80
81
The following figure shows all the tiles necessary for the game.
The Pong game uses two shapes, one for the ball, and one for the bar (made of 3
tiles), as shown in the following figure.
82
There is only one background, as shown in the following figure, which consists of
a rectangular area with wall tiles on all four sides and yellow block tiles on the
top.
In addition to the observer, there are two sprites, ball and bar. As shown in
the following figures, bar has the property of colliding with wall tiles, while
ball collides with both wall and block tiles, and also with the bar sprite
83
84
The bar sprite simply responds to two types of user input events,
LeftArrowPressed and RightArrowPressed, as shown in the
following figures, by moving either left or right by one step.
85
The ball sprite responds to a CollidesSprite:bar event by simply
bouncing off the bar by changing its heading, as shown below.
While sprite bar has an empty run procedure, the procedure definitions for
sprite ball seems complicated, but consists mostly of redundant code, as shown
below.
to run() { bounce() } // returns 1 if the tile at position x, y is a blank tile (tile9), otherwise return 0, and set that tile to blank if it is a block tile to is_empty(x, y) temp { set temp get_tile_at(x, y) if (temp == tile9) { return 1 } else { if (temp != wall) { set_tile_at(x, y, tile9) } }
86
} to bounce() x, y, heading { set x get_x() set y get_y() set heading get_heading() if (y == 16) { // the ball has reached the bottom edge, player loses stop() } // determines whether to change heading depending on the current heading of the ball and whether it has bumped into any obstacles if (heading == 1) { if (is_empty(x, y-1) == 0) { set_heading(3) } else { if (is_empty(x+1, y) == 0) { set_heading(7) } else { if (is_empty(x+1, y-1) == 0) { set_heading(5) } else { fd(1) } } } } else { if (heading == 3) { if (is_empty(x+1, y) == 0) { set_heading(5) } else { if (is_empty(x, y+1) == 0) { set_heading(1) } else { if (is_empty(x+1, y+1) == 0) { set_heading(7) } else { fd(1) } } } } else { if (heading == 5) { if (is_empty(x-1, y) == 0) { set_heading(3) } else { if (is_empty(x, y+1) == 0) { set_heading(7) } else { if (is_empty(x-1, y+1) == 0) { set_heading(1) } else { fd(1) } }
87
} } else { if (is_empty(x, y-1) == 0) { set_heading(5) } else { if (is_empty(x-1, y) == 0) { set_heading(1) } else { if (is_empty(x-1, y-1) == 0) { set_heading(3) } else { fd(1) } } } } } } } Having defined both ball and bar, the observer simply initializes the game by
creating instances of the bar and ball character.
This concludes the implementation of a simple version of the game Pong
(Breakaway) in GameWeaver.
88
Bibliography
Begel, A. (1997) Bongo: A Kids Programming Environment for Creating Video Games on the Web. Master of Engineering Thesis, MIT.
Harel, I., Papert, S. (Eds.) (1991).
Construction Kits and Design Environments: Steps Toward Human Problem-Domain Communication. Human-Computer Interaction. 3. 179-222.
Kafai, Y. (1993). Minds in Play:
Computer Game Design as a Context for Children’s Learning. Ph.D. Dissertation. MIT Media Laboratory.
Kafai, Y., Resnick, M., Eds. (1996).
Constructionism in Practice. Mahwah, NJ: Lawrence Erlbaum.
Martin, F., Mikhak, B., Resnick, M.,
Silverman, B., Berg, R. (2000). To Mindstorms and Beyond: Evolution of a Construction Kit for Magical Machines. In Druin, A. (Eds.), Robots for Kids: Exploring New Technologies for Learning Experiences. San Francisco, CA: Morgan Kaufman Academic Press.
Martin, F., Mikhak, B., Silverman, B.
(2000). MetaCricket: A Designer’s Kit for Making Computational Devices. IBM Systems Journal, Vol.39, Nos. 3&4 – MIT Media Laboratory, pp 795-815.
Mikhak, B., Martin, F., Berg, R., Resnick, M., Silverman, B. (1999). The Children’s Machines: Handheld and Wearable Computers Too. Procedings of the 1999 International Symposium on Handheld and Ubiquitous Computing. Karlsruhe, Germany. Papert, S. (1980). Mindstorms: Children,
Computers and Powerful Ideas. NY: Basic Books.
Papert, S. (1991). Situating
Constructionism. In Y.Kafai, M.Resnick (Eds.), Constructionism in Practice. Mahwah, NJ: Lawrence Erlbaum.
Papert, S. (1993). The Children’s
Machine: Rethinking School in the Age of the Computer. NY: Basic Books.
Repenning, A. (1994). Programming
Substrates to Create Interactive Learning Environments. Interactive Learning Environments. 4(1). 45-74.
Resnick, M. (1994). Turtles, Termites,
and Traffic Jams. Cambridge, MA: MIT Press.
Smith, D., Cypher, A., Spohrer, J.
(1994). KidSim: Programming Agents Without a Programming Language. Communications of the ACM. 37(7). 54-68.