Project Overview Mapwad: A Maze Generation language Team: Ben Smith, Avrum Tilman, Josh Weinberg, Ron Weiss Overview and Summary A high level language for creating mazes rendered in 3 dimensions using Quake. Built in data structures and functions to naturally express a map. Ability to define custom functions to ease implementation of maps Java/C style syntax and semantics Motivation Motivation Designing mazes by hand is tedious and error prone Build large, complex mazes algorithmically Goals Easy to use - intuitive syntax, simple language constructs Flexible - few constraints on maze walls can be at any angle to each other, etc. Concise - able to generate complex maze with few lines of code Language Design The language is designed around highlevel data types that offer an intuitive description of a map Instead of dealing with planes you deal with rooms Mapwad eliminates the need to specify coordinates – All objects are positioned relative to each other Mapwad syntax Java/C – – – – Whitespace ignored Comments /**/ and // Blocks enclosed in {} Function default parameters: • MyFunc(int a,int b=3,int c=4) {…} • MyFunc(1,,10); • MyFunc(1,2); – “dot” operator (built-in types only): • myRoom.Walls[0].Length = 10; Reserved Words Control Flow – if, else, for, while, break, continue, return Primitive Data Types – int, float, boolean, string Values – true, false, null Object Data Types Room – Walls - Super Data Structure Wall Location Thing Built in Functions – – – – – – – boolean Add(Room r, Wall newWall) boolean AddAfter(Wall w, Wall newWall) Remove(Wall w) boolean Attach(Wall a, Wall b, string connectpoint) boolean Close(Room r) boolean IsClosed(Room r) Math Functions Variables – – – – MapStart <Location> MapHeight <float> CeilingTexture <string> FloorTexture <string> Semantics Scoping rules – Global scope – {} blocks have own scope – Rooms and Things automatically added to map Primitive Types – Passed by value – Instantiated when variable is created • int x; //creates a variable and instantiates an int Object types – Passed by reference – Object-typed variables are references – Must be explicitly instantiated • Room r; //creates a reference to a Room • r = Room(); //instantiates a Room object Compiler Components Lexer/Parser Tree Walker – Walks the AST generated by the parser – Checks types, resolves symbols, etc. – Executes the code Internal package – Contains code called by the tree walker to manipulate Mapwad structures Code generator – Creates Quake .map file - text file containing information about contents of map. QBSP – Compiles .map file into Quake .bsp map file that the game understands. Block Diagram Mapwad MapwadLexer MapwadParser MapwadWalker Builtin Functions MWMap qbsp MWGui Sample Code //creates a regular polygon shaped room Room regularRoom(int walls, float length, string texture="BRICKA2_2") { Room newRoom = Room(); float angle = 180*(walls-2)/walls; int i; for(i=0;i < walls;i++) { Wall w = Wall(length,angle,"",texture); Add(newRoom, w); } Close(newRoom); return newRoom; } Map() { Room r = regularRoom(10, 15, "BRICKA2_4"); Room start = regularRoom(4, 5); Attach(r.Walls[0], start.Walls[0]); Thing t = Thing("monster_army", Location(r.Walls[5], "center", 10)); MapStart = Location(start.Walls[3], "center", 2); CeilingTexture = "sky1"; } Compiler Output "sounds" "1" "classname" "worldspawn" "wad" "quake101.wad" "worldtype" "0" { ( 0 0 0 ) ( 100 0 0 ) ( 0 0 1 ) BRICKA2_4 0 0 0 1.0 1.0 ( 0 -1 0 ) ( 0 -1 1 ) ( 100 -1 0 ) BRICKA2_4 0 0 0 1.0 1.0 ( 0 0 0 ) ( 0 0 1 ) ( 0 -1 0 ) BRICKA2_4 0 0 0 1.0 1.0 ( 100 0 0 ) ( 100 -1 0 ) ( 100 0 1 ) BRICKA2_4 0 0 0 1.0 1.0 ( 0 0 0 ) ( 1 0 0 ) ( 0 1 0 ) BRICKA2_4 0 0 0 1.0 1.0 ( 0 0 100 ) ( 0 1 100 ) ( 1 0 100 ) BRICKA2_4 0 0 0 1.0 1.0 } { ( 100 0 0 ) ( 181 59 0 ) ( 100 0 1 ) BRICKA2_4 0 0 0 1.0 1.0 ( 101 -1 0 ) ( 101 -1 1 ) ( 181 58 0 ) BRICKA2_4 0 0 0 1.0 1.0 … What does it look like? Error Checking There are three types of error checking in Mapwad Syntax Error – Caught by the lexer/parser Semantic Error – Caught by the tree walker • Incorrect types, wrong arguments, etc… Runtime Error/Warning – Caught during code generation • Invalid Geometry • Locations outside of map Testing Modular Testing – Each module was tested independently Regression Testing – Basic test cases were reused as code evolved Integration Testing – Modules were combined slowly and tested at every stage Lessons Learned Don’t overextend yourself – Our initial design was too ambitious for a one semester project Fully define interfaces early – We had to modify all our methods late in development Generalize your code – When we found problems we they were resolved without major code revisions Future Work Support more generalized 3D structures More sophisticated error checking Support for more interactive objects – Doors, Elevators, Moving platforms Integrate into a graphical level editor