-
Notifications
You must be signed in to change notification settings - Fork 1
Home
A page with a roadmap, and a bit of Doom engine history which should be applicable to our little project.
- Doom engine stuff which we don't cater for at the moment.
- SSECTORS, SEGS, NODES
- Blockable/non-blockable LINEDEFs. At the moment we don't differentiate between the two. In fact, it's even worse, in DOOM LINDEFs are shared between sectors, we've got seperate LINEDEFs for all our sectors.
- Differences in sector heights - at the moment our world is completely flat.
- Lifts/Crushers, and how to indicate it
- Look at stacked canvases. I want two canvases on top of another. The first one gets used to display the level, the second one is where the sprites/etc. get displayed. We can then alpha blend the two onto another to help us in creating cool effects, perhaps. (Nico/Marlo?)
- Keyboard input (move the viewport with key events) (Marlo?)
- Investigate speed of particle system (Marlo)
- Investigate feasibility of running the game on android using webiew:
- Graphics
- NaCL client!
- particle engine
- fog-of-war
- lighting
- Interface
- keyboard events
- smoother scrolling
- full screen
- Gameplay
- Roaming THINGs. This involves
- movement
- collision detections towards walls
- collision detection between things
- Roaming THINGs. This involves
So, because we are basically doing Doom top-down here, a bit of background about the Doom internal engine structure. Some good resources on the Doom engine are:
- http://doom.wikia.com/wiki/Doom_rendering_engine - a good basic overview
- http://www.gamers.org/dhs/helpdocs/dmsp1666.html - the Doom Engine Unoffial Specs. This is the whole of the knowledge about the Doom engine built up by the community in the past 15 years. Everything you need to know should be in here.
I will provide a basic explanation of what is applicable to the our interpretation of doom, as it stands at the moment.
Doom has an internal filesystem, which works like a directory structure on a normal filesystem. The Doom engine uses this filesystem internally to get all textures,sprites,maps,sounds,musics etc. Each entry in the filesystem is called a lump. Lumps for the maps are MAP01 -> MAP32 in Doom 2, and E1M1 -> E4M9 in Ultimate Doom, for example. Textures are stored in lumps with the name of the texture, ie. FWATER_4. The data structure in the different lumps depends on what the lump is used for. These are the WAD files that we all know and love. There is an IWAD which contains a complete set of data, this is doom.wad, doom2.wad, which contains everything needed for a complete Doom 1 or Doom 2 game. Then you can "patch" the internal filesystem at startup using custom wads, or PWADS (Patch Wads), using the -file parameter on the old doom engine. This is how we used to load custom levels.
I've got a script in python which can export (some) data from a WAD file to a JSON file loadable by our engine, which I used to create MAP01.json for example. This script we can use to convert ANY DOOM WAD in the world, which gives us about 20 thousand million billion levels to play with in our little project.
So, as I said, a WAD file is a bunch of lumps. At the moment, what is of interest to us, are the MAP and texture lumps.
- Texture lumps are interesting because they define, well, the textures.
- MAP are empty lumps which simply define the start/end of map data. The actual map data is stored as a collection of VERTEXES,SECTOR,LINEDEF,SIDEDEF and THING lumps (those are of interest to us at the moment). There are a bunch of additional lumps like BLOCKMAP which is an optimisation tool which the doom engine used to increase collision detection speed, but for now we are interested in VERTEXES,SECTORS,LINEDEFS,SIDEDEFS and THINGS.
Doom maps are basically a bunch of connected polygons, defined by points. The VERTEXES lump defines these points. Each of them is simply an (x,y) pair on the Doom coordinate system (which is a cartesian coordinate system, as opposed to the coordinate system used by the HTML 5 canvas, which is non-cartesian (ie. y works from top to bottom)).
A LINEDEF is simply a line connecting to vertexes. A LINDEF has an "a" vertex and a "b" vertex. A begin the origin of the line, and b the end. Now, every line in Doom space has got two sides, left and right. The meaning of left and right has got to do with the direction of a line. If you orient yourself on the start vertex, and look towards the end vertex, the left linedef, is, well the "side" of the line pointing towards the left, and right vice versa. The "left" and "right" sides are optional, only one needs to be defined, but a line can have two. A linedef with only one sidedef is called single-sided, and a linedef with two sidedefs is called "double-sided".
A single-sided linedef is never crossable in the doom engine. These are usually used for walls. A linedef with two sides can be crossable for the one, but not the other, based on the definition of the seperate SIDEDEFs. More on this later.
For each side of each LINEDEF, there is an entry in the SIDEDEF lump. Each SIDEDEF has a number of properties, including whether it is passable or not, and three texture pointers. Each SIDEDEF has 3 textures pointers:
- lower texture - this is the texture that gets displayed at the bottom of the side, ie. the bottom part of a stair.
- upper texture - this is the texture that gets displayed at the top of the side, ie. the ceiling.
- middle texture - this is the texture that gets displayed in the middle of the side (the y part between the floor and the celing). This for example gets used to do windows - you have a sector with floors higher, and ceilings lower, than the adjacent sector. The lower texture defines the "bottom" of the window frame, the upper texture the "upper" part of the frame. Then you have a translucent texture in the middle with some decorations to simulate an arbitrary window form.
The Doom engine uses SIDEDEFs for collision detection, and crossing between sectors. If I am in sector 1, and wanting to pass to sector 2, which between them has a LINEDEF x, the doom engine calculates which SIDEDEF of x points to sector 1, and then determines whether you can pass or not by first checking the height difference between the sectors, and then checking the passable flag of the sidedef.
SIDEDEFS also have triggers - this what gets "triggered" when you press space on a wall, to toggle a switch, open a door, etc. These triggers usually have effect on SECTORs.
A SECTOR is completely defined by LINEDEFs (actually the SIDEDEFS from the LINEDEFS). One sided LINE-DEFS form impenetrable walls, two sided LINEDEFs makes passing between sectors possible.
A sector also has 2 textures, floor and celing, as well as floor height and a ceiling height. So Doom was in fact 3D in this sense - it just had some limitations, but there was a z-coordinate involved.
Sectors also have a light level, which determines how dark/bright the sector is. Sectors can have special properties as well, like lava hurting the player, triggering some action etc. The doom engine also had the capability to during gameplay change the heights of the floor or celing, this is how they did lifts or crushers for example. Teleporters are also a special sort of sector.
THINGs are what makes Doom an actual game. Sectors,linedefs,textures and sidedefs are interesting, but if there is nothing populating the world, then we have no game.
Implementing THINGs is thus an integral part of making this a fun game. THINGs in doom include players, monsters, barrels, items, health, ammo, etc. They are represented by sprites. Monster and player things have 8 different sprites, each for a different angle. The engine calculates the angle between the player and the thing in question and then displays the "sprite" for that angle.
The behaviour of the monsters are paramount to the doom experience. The engine has got hardcoded algorithms for each of the monsters. These can be found online, and we will study it when we start implementing THINGS.