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