GameWeaver: a Construction Kit for Kids ... Create Video Games for Handheld Devices by

advertisement
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
Feb
1ince
2001
Certified by
Bakhtiar Mikhak
Psis Supervisor
Arthur C
Accepted by
th
Chairman, Department Committee on Graduate Theses
MASSACHUSETS INSTITOTE
OF TECHNOLOGY
JUL 3 1 Z0
LIBRARIES
BARKAE
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
Acknow ledgm ents .............................................................................................................
iv
C hap
t e r 1 Introduction ......................................................................................
1
C hap
t e r 2 M otivation .........................................................................................
4
2.1
W hy Construction Kits?...............................................................................
4
2.2
2.3
W hy Videogam es?....................................................................................
Why handheld devices?............................................................................
5
6
Ch a p
t e r 3 Previous w ork ....................................................................................
Program ming Construction Kits ...........................................................
3.1.1
Logo.....................................................................................................
3.1.2
Agentsheets and Cocoa (Kidsim ).................................................
3.2
V ideogam e Construction Kits..............................................................
3.2.1
Pinball Construction Set ................................................................
3.1
3.2.2
"Click" Series....................................................................................
3.2.3
Stagecast Creator ...............................................................................
3.3
Construction Kits for H andheld D evices ............................................
C h ap ter 4 D esign .............................................................................................
4.1
4.2
9
9
9
10
11
12
12
13
14
16
16
G am e D esign Space...............................................................................
Game Components and Representation (Sample project: Pacman) .19
20
G raphical Com ponents ..................................................................
4.2.1
4.2.1.1
4.2.1.2
4.2.1.3
Tiles ...........................................................................................
Shapes ......................................................................................
Backgrounds ............................................................................
4.2.2
Program m ing Com ponents ...........................................................
4.2.2.1 Procedures...............................................................................
4.2.2.2 Event H andlers .......................................................................
Sprites and Characters .....................................................................
4.2.3
O bserver (the special sprite) .................................................
4.2.3.1
Program ming Language .........................................................................
4.3
4.3.1
Text-based vs. G raphical.................................................................
Compiled vs. Interpreted ................................................................
4.3.2
4.3.3
D etailed Specification.....................................................................
21
22
24
26
26
28
31
34
35
36
37
39
4.3.3.1
4.3.3.2
D ata Types ...............................................................................
V ariables ...................................................................................
39
39
4.3.3.3
4.3.3.4
O perators and Expressions.................................................
Control Statem ents................................................................
40
41
4.3.3.5
Procedures...............................................................................
C h a p t e r 5 Im plem entation ...................................................................................
5.1
5.2
O verall System ........................................................................................
IDE (Integrated Development Environment) ..................................
41
43
43
44
5.2 .1
5.2.2
G U I....................................................................................................
Game Objects Layer .......................................................................
. 45
46
5.2.3
Interpreter.........................................................................................
47
5.2.3.1
Byte C odes ..............................................................................
47
5.2.3.2
5.2.3.3
Interpreter Implementation for IDE ..................................
Interpreter Implementation for Handheld Devices .........
48
49
5.2.4
C ompiler............................................................................................
5.2.4.1
5.2.5
From Source Code to Byte Code..................
GWE (GameWeaver Executable) file ..........................................
50
50
57
A Sample Byte-Code Interpreter: Game Interpreter for the Palm
5.3
57
P latfo rm .......................................................................................................................
58
Palm Application: GameWeaver.prc ............................................
5.3.1
5.3.2
Conduit: GameCond.dll..................................................................61
C h ap t e r 6 C onclusion.......................................................................................
65
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) .......................................................................
APPENDIX I:
B ib lio grap h y .......................................................................................................................
ii
79
89
LIST OF FIGURES
Page
Number
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
12
Figure 3: Pinball construction set (mac version).....................................................
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
17
different types of gam es ................................................................................
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
23
Figure 10: "Edit Shape" window for Pacman game ..............................................
23
Figure 11: "Edit Shape" window for Tetris game ...................................................
25
Figure 12: "Edit Background" window for Pacman game ....................................
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
28
g ame .......................................................................................................................
30
Figure 15: Flow chart representing sprite foo ..........................................................
Figure 16: Examples of how two counters for detecting the number of collisions
31
can becom e out of sync.................................................................................
33
Figure 17: Properties panel for pacman sprite.........................................................
35
Figure 18: Observer in Pacman Game.....................................................................
Figure 19: Overall system design involving a platform independent IDE and
43
interpreters for individual handheld devices...............................................
Figure 20: Block diagram representation of the four main components of the
45
ID E ........................................................................................................................
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
iii
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.
iv
Chapter 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 theirgeneration."
Seymour Papertin Children'sMachine (1993)
In
the past few years,
small
computational
toys such as Gameboy TM ,
TamagochiTM, Cybiko TM , Friend.link TM , and Groove ConnectionTM 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 devices'. What makes this approach particularly appealing is
1Website: http:/llk.media.mit.edu/people/mikhak/projects/
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, PocketPCTM machines, Palm Pilots, Cell phones,
digital cameras, and Color GameboyTM 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
2
(Kafai 1993), but also come to
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.
3
Chapter 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
4
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
5
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, PocketPCTM machines, and GameboyTM 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
6
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 TM 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 GameboyTM,
Gameboy TM 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 PocketPCTM 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://lk.media.mit.edu/projects/
7
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.'
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/
8
Chapter 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
3.1.1
Programming Construction Kits
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 Al applications.
modularity, extensibility, interactivity, and flexibility.
9
Logo's main features are
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 LCSI 4 (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
10
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.
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.
11
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.
it File Edit KI fiodies Help tral2
0
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
Khik & 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.
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.
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.
13
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
PocketPCTMs, 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
14
demand for any such construction kits for children yet.
But with prices of
handheld devices dropping each year (Pahn'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 Pahn Pilots and PocketPC
TM
s, much like
Gameboy TM 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.
15
Chapter 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.
16
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.
Expertise/Knowledge
(e)
3D
2D
arcade
platform
Development time (t)
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
17
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)
arcade
2D platform
3D
Development time (t)
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.
18
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
Action (Eventhandlers)
Sprite
Basic programming component
A programming component for
handling events
A game character that has certain
behaviors and attributes associated
with it
Table 1: Definition of game components
19
These game components form a hierarchical structure since some are used for
building others. For example, sprites consist of shapes,pmcedures, 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
I I,
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.
20
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
21
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 GameboyTM , 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.
22
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
23
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
24
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 GameboysTM.
Figure 12 shows one of the backgrounds used in the Pacman game that
represents a maze.
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 pixelbased layer. The IDE can supply an image loader so users can load external
25
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 (Eventhandlers), 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 storedprocedures,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
gettileat.
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.
26
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.
27
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.
if (getglobal(countdon) > 0)
s
dieo(
Figure 14: Example of an action (event-handlers) for ghost sprites in Pacman game
28
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.
29
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 space', 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 collidi ng
no
anybody else?
yes
Increm ent
counter
Move forward 1
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 offoo 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
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.
30
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.
countr=
0
counter =
0
counter =
0
counter = 0
countrt& = 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: patman, whose
31
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.
32
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
33
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
getnumberof 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
34
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.
Vigure It5: Unserver m iacman
4.3
uame
Programming Language
This section discusses the programming language used for programming sprites.
We first give arguments as to why GameWeaver's programming language is textbased
(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.
35
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 textbased 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.
36
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.
37
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 TMs) 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
38
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
4.3.3.1
Detailed Specification
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
39
variables can be accessed using the getglobal
using the setglobal
stored procedure, and written
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
and setlocal
getlocal
stored procedures.
Temporary variables must be declared at the beginning of a procedure.
have even smaller scopes than local variables.
They
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 +,
operator
==,
Iand
-.
-,
*,
Logic operators include the binary operators <,
=.
/ , and the unary
>,
<=
> =,
Since boolean is not a valid data type, the value of a boolean
40
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
>
+ 5) is6.
0)
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 f oo refers to procedure bar, f oo does not have to
be declared after bar. Therefore, procedures can also be defined recursively.
Procedure declaration:
to <procedurename> (<argi>, <arg2>, ... , <argn>)
<tempvarl>, <tempvar2>, ... , <temp-varm>
{
<p rocedure.body>
}
Procedure call:
<procedurename>(<arg1>, <arg2>, ...
,
<argn>)
Figure 19: Syntax for procedure declarations and procedure calls
41
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.
42
Chapter 5
IMPLEMENTATION
5.1
Overali 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.
IDE
binary executable
Interpreter
PC
Handheld
Devices
Gameboy
Interpreter
Palm
Interpreter
PocketPC
Interpreter
(need to do)
(need to do)
Figure 20: Overall system design involving a platform independent IDE and
interpreters for individual handheld devices
43
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 bytecode 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
44
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
:read/write
Game
Objects
project file
source code
graphical
information
Compiler
.gwe file
byte code
Interpreter_
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.
45
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
compiler/interpreter.
communication
between
the
GUI
and
the
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.
46
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 ULDs 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
47
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.
Example
Category
Operator
Display Control
PLUS, LESS THAN
GETTILEAT,
SETBACKGROUND
Data Access
GET_X,
SETHEADING,
SETGLOBAL
System
GETSTACKPOINTER,
SETFRAMEPOINTER
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
48
than other
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.
Runtime characters:
observer (runtime)
pacman
ghost1
ghost2
sqtark.
...
X
STOP
heading
speed
shape
heading
speed
shape
heading
speed
shape
localvas
local vas
ocal vasi
local var
"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
49
This is not a difficult task given the
GWE (GameWeaver executable) files.
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.
source
code
1PParser
parse
tree
10Code
Generator
byte
code
optimizerr
Figure 23: Compiler Implementation represented in three stages
The following sections discuss each stage in more detail.
50
-Op
byte
code
*
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).
source code
JLex
Yyle
-Yylex.java
symbols
parser.java
Cup
parsercup
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 onedimensional 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.
51
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 Treelf 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.
Treelf
TreeBlock
ExprBinary
ExprId
x
Operator
>
CallExpr
ExprNum
0
ExprId
Exp
inary
fd
ExprId
x
+
Figure 25: Parse tree corresponding to source code: "if (x>O)
*
Operator
ExprNum
1
{ 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
52
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 "<expri> <op> <expr2>" where <expri> and
<expr2> are themselves expressions and <op> is an Operator (such as + or -).
We use [expri] and [expr2] represent the results of flattenizing <expri> 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:
<exprl> <op> <expr2>
Example:
=>
[exprl] [expr2] [op]
3*(1+2)
NUM8
I
NUM8
ExprBinary
3eP
ExprBinary
I
+
NUM8
2
PLUS
2
[e xpri]
[expr2]
AUT
1
T
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
53
controlled by the value of a condition expression. Figure 27 demonstrates how an
if
tree is flattenized using two additional byte codes IFELSE
-then-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, IFELSE 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, IFELSE increases the
program counter by y, and executes [elseblock], as desired.
Rule:
if (<cond>) { <thenblock> } else { <elseblock> } ->
[cond] [sizeoftthenblock]+2] IF ELSE [thenblock]
[sizeoflelseblock]] JUMP [elseblock]
Example:
if (l>0) { stop() } else { execute()
Treelf
NUM8
NUM8
ExprBinary
EzprNum Operator
1
>
CallExpr
execute
CallExpr
stop
EzprNum
-
0
GREATERTHAN
3
IFELSE
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.
54
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
55
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.
0
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.
56
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.
57
Directory:
pacman.gwe
tetris.gwe
Database:
GanrWeaver.prc
(palm application)
read
pacman
4-
write
GameCond
(conduit)
tetris
Palm
PC
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.
58
(Exit Game)
Figure 29: Pacman played on Palm (emulator)
59
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 frunctionalities 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
60
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.dlI 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.
61
rigure .)u: tonauwt uonnguranon wmcow
62
: Conduit contiguration settings tor Gametond
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
63
the desktop, and it will automatically get installed/erased during the next HotSync
operation.
64
Chapter 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 PocketPCTM machines and
Color Gameboys TM 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
65
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 singleplayer 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 leam
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.
66
APPENDIX I:
BYTE CODES
Name
Byte
code
Behavior
GETTILEAT
0
Pop <x>, then <y>; push the UID
of the tile at position in (<x>, <y>)
in the current background
SETTILEAT
1
NUMBER8
2
NUMBER32
3
COLLIDESTILE
4
Pop <x>, <y>, and <tileid>; set the
tile at position (<x>, <y>) to be the
tile with UID <tileid>
Push the numeric value of the
following byte code onto the stack
Push the numeric value of the next
four byte codes (32-bit integer) onto
the stack
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
COLLIDESCHAR
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
GOTO
6
push 0
Pop <boc>; set program counter to
<boc>
IFELSE
7
Pop
JUMP
8
SETXY
10
GETX
12
GETY
13
GETHEADING
14
PLUS
15
<delta>,
pop
<cond>;
if
<cond> is equal to 0, increment
program counter by <delta>
Pop <delta>; increment program
counter by <delta>
Pop <y>, pop <x>; sets the current
character at position (<x>, <y>)
Push x position of current character
on the stack
Push y position of current character
on the stack
Push the heading of current character
on the stack
Pop <b>, then <a>; push <a>+<b>
67
MINUS
LESSTHAN
16
17
GREATERTHAN
18
EQUALS
19
SETHEADING
21
RANDOM
22
GETFRAMEPOINTER
23
SETFRAMEPOINTER
24
AND
25
OR
26
NOT
27
POP
28
LESSTHANOREQ
29
GREATERTHANOREQ
30
GETPROGRAMCOUNTER
31
GETSTACKPOINTER
32
GETSTACKAT
33
MUL
DIV
34
35
Pop <b>, then <a>; push <a>-<b>
Pop <b>, then <a>; push 1 if <a>
less than <b>, otherwise push 0
Pop <b>, then <a>; push 1 if <a>
greater than
<b>, otherwise
push 0
Pop <b>, then <a>; push 1 if they
are equal, otherwise push 0
Pop <heading>; set heading of
current character to <heading>
Pop <n>; push a random integer
between 0 and <n>-1 onto stack
Push current frame pointer on the
stack
Pop <fp>; Set current frame pointer
to be <fp>
Pop <a>, then <b>; push 1 if both
<a> and <b> are greater than 0,
otherwise push 0
Pop <a>, then <b>; push 1 if either
<a> or <b> is greater than 0,
otherwise push 0
Pop <a>; push 0 if <a> is greater
than
0, otherwise push
1
Pop <n>, then pop the next <n>
numbers from the stack
Pop <b>, then <a>; push 1 if <a> is
less than or equal to <b>, otherwise
push 0
Pop <b>, then <a>; push 1 if <a> is
greater than or equal to <b>,
otherwise push 0
Push the value of the program
counter on the stack
Push the value of the stack pointer on
the stack
Pop <location>; Push the value of
the stack at <location>
Pop <b>, then <a>; push <a>*<b>
Pop <b>, then <a>; push <a>
divided by <b> (truncates remainder)
MOD
<b>, then <a>; push the
Pop
remainder of <a>/<b>
36
68
SETNUMBERAT
Pop <location>, pop <value>; Set
37
the value of the stack at <location to
be <value>
CREATECHARACTER
38
Pop <type> <x>, <y>, <heading>,
<speed>; creates a runtime character
of the sprite type <type>, with initial
GETSTACKRELATIVEAT
<y>),
heading
position
(<x>,
<heading>, and speed <speed>
Pop <delta>; push the value of the
39
stack at the current stack pointer plus
<delta>
GETHEADINGDX
Pop <heading>; push either 1, 0, or -
40
1 according to the xcor direction of
<heading>
GETHEADINGDY
Pop <heading>; push either 1, 0, or -
41
1 according to the ycor direction of
<heading>
EXECUTE
42
Switches from executing the observer
to executing all other characters
STOREREGA
43
Pop <value>; set register to <value>
GETREGA
44
Push the value of the register onto
stack
STOP
45
Destroys all runtime characters and
resumes executing the observer
SETVARIABLE
46
Pop <varjindex>, pop <value>; sets
the number at position frame pointer
+ <var_index> on the stack to be
<value>
NUMBEROF
Pop <spritejuid>; push the number
47
of runtime characters of sprite type
<sprite-uid>
Pop
<bg_uid>;
set
the
current
SETBACKGROUND
48
PRINT
49
Pop <number>; Prints <number>
50
51
Pop <boc>; push current program
counter to stack, set program counter
to <loc>
Pop <boc>; set program counter to
52
<b0c>
Pop <y>, then <x>; push 1 if the
background to background <bg..uid>
JTS
(jump to subroutine)
RTS (return to subroutine)
COLLIDESTILEAT
current character collides with the tile
at (<x>, <y>) in current background
69
SETGLOBAL
Pop <index>, pop <value>; set the
53
value of global variable with index
<index> to <value>
GETGLOBAL
54
SETSHAPE
55
Pop <index>; push the value of
global variable with index <index>
GETSHAPE
56
DIE
57
SETLOCAL
58
Pop <shape-uid>; Attempts to set
the shape of current character to
<shapejuid>, push 1 if succeeded, 0
otherwise
Push the uid of the current character's
shape to the stack
Kills the current character
Pop <index>, pop <value>; set the
value of the local variable with index
<index> to <value>
GETLOCAL
Pop <index>; push the value of local
59
variable with index <index> to stack
GETTILEOFSHAPEAT
Pop <shapeld>, <x>, and <y>; push
0 if position (<x>, <y>) of shape
with UID <shapeld> is empty,
60
otherwise push the UID of the tile at
position (<x>,<y>) of the shape with
UID <shapelD>
PAUSE
61
Pop <t>; Pause the entire game for
<t>/10 seconds
GETVISIBLE
62
Push 1 if current character is visible, 0
SETVISIBLE
63
SETSCORE
64
GET SCORE
SETSCOREVISIBLE
65
66
otherwise
Pop <visible>; set current character
to be visible if <visible> is greater
than 0, to be invisible otherwise
Pop <score>; set the score to be
displayed to be <score>
Push the score being displayed
Pop <visible>; set score to be visible
if <visible> is greater than 0, to
invisible otherwise
GETSCOREVISIBLE
67
Push 1 if score is visible, 0 otherwise
NOP
100
A helper byte code that does not
perform any operation
ENDTREEBLOCK
101
Same as above
70
APPENDIX II:
GRAMMAR
Meta-not ation:
<foo>
means foo is a nonterminal.
(in bold font) means that foo is a terminal
foo
means
zero or one occurrence of x
[x]
x*
means zero or more occurrences or x
a comma-seperated list of one or more x's
seperates alternatives
->
<procedure>
<block> ->
{
to <id> ([<id>+,] ) [<id>+,] <block>
<statement>*
<statement> ->
}
<methodcall>
I if ( <expr> )
<block> [ else <block>]
while ( <expr> ) <block>
I return [<expr>]
set <id> <expr>
I <block>
<method_call>->
<expr> -> <id>
<id>([<expr>+,])
I <methodcall>
<literal>
I <expr><binop><expr>
I -<expr>
I (<expr>)
<binop>
<literal> ->
->
+ I - I * I / I < I > I <=
[-]<digit><digit>*
<digit>
->
0111213141516171819
<id>
->
<alpha><alpha>*
<alpha>->
alblcl.....IzIAIBICI....IZ
71
>=
&&
APPENDIX III:
Procedure
setheading(<heading>)
get-headingQ
rt(<degree>)
lt(<degree>)
get-xo
getyo
setxy(<x>, <y>)
fd(<number>)
getspeed(
setspeed(<speed>)
create(<sprite>, <x>, <y>,
<heading>, <speed>)
execute)
stopQ
die(
Pause(<time>)
<y>,
settile-at(<x>,
<tile>)
setbackground(<backgrou
nd>)
get-shapeQ
set shape(<shape>)
STORED PROCEDURES
Definition
Sets the heading of current character to
<heading>, returns 0
Returns the heading of current character
Rotates the heading by <degree>*45 degrees
clock-wise, returns 0
Rotates the heading by <degree>*45 degrees
counter-clock-wise, returns 0
Returns the x position of current character
Returns the y position of current character
Attempts to set the position of current
character to <x>,<y>, returns 1 if successful,
0 otherwise (due to collisions)
Attempts to move current character forward
<number> steps, returns 1 if successful, 0
otherwice (due to collisions)
Returns the speed of current character
Sets the speed of current character to
<speed>, returns 0
Creates an instance of <sprite>, initializing it's
x, y positions, heading, and speed variables to
<x>,
<y>,
<heading>
and <speed>
accordingly, returns 0
Tells all existing characters to start running,
returns 0 (can only be called by observer)
Deletes all existing characters except the
observer, and resumes execution from where
the last "execute" procedure was called in the
observer, returns 0
Kills the current character
Pauses the entire game for <time>/10
seconds
Sets the background tile at position <x>,<y>
to be <tile>, returns 0
be
background
to
Sets
the
entire
returns
0
<background>,
Returns the shape of current character
Sets the shape of current character to
72
<shape>, returns
get-global(<vamame>)
set-global(<vamame>,
<value>)
getjlocal(<varname>)
setlocal(<varname>,
<value>)
get-visibleQ
setvisible(<visible>)
Returns the value of the global variable
<vamame>
Sets the value of the global variable
<varname> to <value>, returns 0
Returns the value of the local variable
<varname>
Sets the value of the local variable <varname>
to <value>, returns 0
Returns 1 if the current character is visible, 0
otherwise
Sets the current character to be visible if
<visible> is 1, and invisible if otherwise,
returns
random(<max>)
set score(<score>)
getscore(
setscorevisible(<visible>)
0
0
Returns a random number between 0 and
(<max>-1)
Sets current score to <score>, returns 0
Returns the current score
Sets the score to be visible if <visible> is 1,
and invisible if otherwise, returns
get score_visible)
0
Returns 1 if the score is currently visible, 0
otherwise
get tileofshape at(<shap
Returns the UID of the tile at position (<x>,
e>,<x>, <y>)
<y>) in <shape>
number-of(< sprite>)
Returns the number of <sprite> characters in
the game
Displays <num> in a dialog box, returns 0
print(<num>)
used for debugging)
73
GWE FILE FORMAT
APPENDIX IV:
The GWE (GameWeaver Executable) file format stores game objects
the
Observer)
Sprites
and
Backgrounds,
(Tiles,
Shapes,
Each record contains a
sequentially, consisting of records.
the same format among
The header is
header and data section.
It also contains information identifying the type
all objects.
of data(object) contained in the data section.
File
The First record in the file is the GWE
contains general information about the file.
header,
it
Size
(Bytes)
Data Type
Description
12
Char[10]
4
int
used
just
Always
"GAMEWEAVER01",
recognize the start of the file
The Number of Tiles in the File
4
4
4
Int
Int
Int
The Number of Shapes in the File
The Number of Backgrounds in the File
The Number of Sprites in the File
4
Int
Total Number of Objects in File
(Inc
Observer)
=
Sprites
+
Tiles
+
Backgrounds
+
4
int
Number of Global Variables
to
Shapes
All Objects have the following Header Format
Data Type
Description
Size
(Bytes)
4
int
The length of the data
element)
This can
be
used
to
(including
skip
this
record if it isn't recognized
4
4
Int
Int
4
Reserved
Object Identifier (UID)
Object type identifier
0 = Error
1 = Tile
2 = Shape
3 = Background
4 = Sprite
5 = Observer
74
this
entire
Tile Format
Size
(Bytes)
16
Data Type
Description (has Tile as Object Type)
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
Data Type
Description (has Shape as Object Type)
(Bytes)
16
HEADER
AS ABOVE
16-80
UID[4] [4]
of
Tile
Tile
Grid,
consisting
Identifiers, read left to right, top to
bottom
Background Format
Size
(Bytes)
Data Type
Description(has
Type)
16
HEADER
AS ABOVE
UID[20][18]
Tile
Grid,
Identifiers,
20 x
x 4
18
Background
as
Object
consisting
of
Tile
left
to right,
top to
bottom
Eventhandler Format
Size
(Bytes)
Data Type
4
4
4
4 x L
Int
Int
Int
Int[L]
Description
ByteCode Offset
Event Id
L - length of Parameter list
List of EventHandlerParameters
_This
is Different for every Handler
Sprite Format
Size
Data Type
Description
Bytes
16
HEADER
AS
ABOVE
(has
Sprite
Type)
4
4
UID
Int
Shapes
Number Of Local Varibles
75
as
Object
-
4
Int
T
4 x T
4
UID[T]
Int
List of Colliding Tiles
S Length of Colliding
Length of Colliding Tile List
Shapes
List
4 x S
4
UID[S]
Int
List of Colliding Shapes
Length of ByteCode
BCL
4
Byte[BCL]
Int
Byte Code
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.
76
APPENDIX V:
SYMBOLS USED IN PARSER
IMPLEMENTATION
Symbol Name
SUBOP
Value
ADDOP
+
MULOP
*
-
DIVOP
/
MODOP
%
ANDOP
OROP
&&
EQOP
NEQOP
LESS OP
GREATEROP
LESSEQOP
GREATEREQOP
IF
ELSE
WHILE
LBRACE
RBRACE
LPAREN
RPAREN
RETURN
COMMA
NUMBER
=
<
>
<=
>=
If
Else
While
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,
{
}
Return
,
any number (3, 5, 1000000)
I e.g.
"pacman",
"mazel"
77
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
CallExpr
ExprBinary
ExprId
ExprNum
ExprUni
Operator
Procedure
ReturnInstr
Treelf
TreeSet
TreeWhile
Representation
A procedure call
A binary expression
A simple expression consisting of a single variable
A simple expression consisting of a single number
A negated expression
A binary operator
A procedure definition
A return instruction
An if statement
A set instruction
A while statement
78
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.
79
80
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.
81
. .. - , - -- -
-
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
82
- I
- Ik=-Aet-
en
....
..
.....
.. ....
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.
84
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
//
it
to blank if
(tile9), otherwise return 0, and set that tile
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) {
settile-at(x, y, tile9)
85
}
}
}
to bounce() x, y, heading {
set x getx()
set y gety()
set heading getheading()
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) {
setheading(3)
} else {
if (isempty(x+l, y) == 0) {
set-heading(7)
} else {
if (is-empty(x+1, y-1) == 0) {
setheading(5)
} else {
fd(l)
}
}
}
} else {
if (heading == 3) {
if (isempty(x+l, y) == 0) {
set-heading(5)
} else {
if (isempty(x, y+1) == 0) {
setheading(l)
} else {
if (is-empty(x+l, y+1) == 0) {
setheading(7)
} else {
fd(1)
}
}
}
else {
if (heading == 5) {
if (isempty(x-1, y)
setheading(3)
} else {
86
==
0) {
if
==
(is-empty(x, y+1)
0)
setheading(7)
} else {
if (is-empty(x-1, y+1)
0)
se t_heading(l)
} else {
fd(1)
}
}
}
}
else {
if (isempty(x, y-1) ==
0)
{
setheading(5)
}
else {
if (is-empty(x-1, y) == 0)
set_heading(l)
} else {
if (isempty(x-1, y-1)
==
0) {
setheading(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.
87
This concludes the implementation of a simple version of the game Pong
(Breakaway) in GameWeaver.
88
BIBLIOGRAPHY
Vol.39, Nos. 3&4 - MIT Media
Laboratory, pp 795-815.
Begel, A. (1997) Bongo: A Kids
Programming Environment for
Creating Video Games on the
Web. Master of Engineering
Thesis, MIT.
Mikhak, B., Martin, F., Berg, R.,
Resnick, M., Silverman, B. (1999).
The Children's Machines:
Handheld and Wearable
Computers Too. Procedingsof the
1999 InternationalSymposium on
Harel, I., Papert, S. (Eds.) (1991).
Construction Kits and Design
Environments: Steps Toward
Human Problem-Domain
Communication. Human-Computer
Interaction. 3. 179-222.
Handheldand UbiquitousComputing.
Karlsruhe, Germany.
Papert, S. (1980). Mindstorms: Children,
Computers and Powerful Ideas. NY:
Basic Books.
Kafai, Y. (1993). Minds in Play:
Computer Game Design as a
Context for Children's Learning.
Ph.D. Dissertation. MIT Media
Laboratory.
Papert, S. (1991). Situating
Constructionism. In Y.Kafai,
M.Resnick (Eds.), Constructionism
in Practice.Mahwah, NJ: Lawrence
Erlbaum.
Kafai, Y., Resnick, M., Eds. (1996).
Constructionismin Practice.Mahwah,
NJ: Lawrence Erlbaum.
Papert, S. (1993). The Children's
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.), Robotsfor Kids: Exploring
New TechnologiesforLearning
Experiences. San Francisco, CA:
Morgan Kaufman Academic
Press.
Machine: Rethinking School in the Age
of the Computer.NY: Basic Books.
Repenning, A. (1994). Programming
Substrates to Create Interactive
Learning Environments. Interactive
LearningEnvironments. 4(1). 45-74.
Resnick, M. (1994). Turtles, Termites,
and TraffcJams. Cambridge, MA:
MIT Press.
Martin, F., Mikhak, B., Silverman, B.
(2000). MetaCricket: A Designer's
Kit for Making Computational
Devices. IBM Systems Journal,
Smith, D., Cypher, A., Spohrer, J.
(1994). KidSim: Programming
Agents Without a Programming
89
Language. Communications of the
ACM. 37(7). 54-68.
90
Download