Jump to content

Flexman

Members
  • Posts

    916
  • Joined

  • Last visited

Everything posted by Flexman

  1. I think the key phrase here is "expectation management". Another key phrase...and it's really...I mean really hard to take this one in, I find it hard to visualise this one..."Man century". That's the level of effort involved in some games now. Funny you saying that, one of my fav old games was written by Sandy White (circa 1983), built a virtual city in hex. He was an architect not a programmer by trade. You can even play it from a link here... http://sandywhite.co.uk/fun/ants/ Nothing wrong in being successful though. Minecraft deserves it's success, it just happened to give kids what they really wanted instead of what game designers have traditionally been telling everyone what they wanted. I watch my kids use it for all kinds of things. But most of all they use it to tell their OWN stories and share them. True there's a lot of cynical exploitation, that's any media for you. Find a wagon, chuck a band on it. Not sure I have much use for another 3D mobile engine when I have two to choose from, although one isn't very good. You still have the same problem of creating fully fleshed out ideas in code regardless. If I can sit down with LE3, drag an animated FBX cartoon boy character onto a plane, attach a third-person controller script, a cube and a pickup trigger and run it on an iPad so I can control him to pick-up the cube...do all that in under 15 mins I might be sold. That's the kind of usability I'm used to today.
  2. I miss my Action Man. This is a great tool for traditional stop motion animators. I dare say it's possible to build your own using resistive plastics or flexible strain gauges such as these http://www.tekscan.com/flexible-force-sensors Just add talent.
  3. Here's a rather extreme example. A desert scene I generated using the "Desert" procedural modifier on a dense flat grid. The quality of the the dune ridges is filly dependent on the resolution of the base terrain grid. Once you're happy with construction after adding lighting and shadow maps you can create the mesh layer with little loss of visual quality. You can see the difference in wireframe... And here's the same scene lit normally... If I want to keep a really high resolution mesh in the middle because my action scene requires an oasis then I simply retain the high-res terrain tile or generate a higher resolution mesh for that centre tile. You can mix and match resolutions to your hearts desire, one caveat, watch out for gaps between different resolution tiles. Any gaps require you hand edit individual vertices to fix it. Normally these mesh layers are used on plaftorms that don't support heightmaps (e.g. iPhone Unity pre 3.5) but have application for scene construction elsewhere. Both formats are exported, you can still use the regular heightmap and the lower detail mesh (however many LODs you choose to make).
  4. I've been using something called GROME (GROund Modeling Environment) for a while now, it's a tool for creating realistic landscapes through a mix of procedurally generated techniques and hand editing. Imagine a system blending 3D MAX modifiers for geometry with Photoshop layering for textures and effects. You can export the result as geometry and textures for a variety of engines. I was talking about the problems of rendering large scale terrains recently and the topic of using "tiles" came up again. This is what I've been using GROME for (on a non Leadwerks project). It works on huge terrain sets, paging in as required and splits them up into separate zones. Each zone can have different resolutions and materials as needed. If you're working on large worlds this is pretty much the business for doing it. Each zone is exported as a discrete mesh. Not only that, you can create multiple LODs for each tile. Simplify individual meshes as required or export the native height-map for that one area. While working on art pipelines I wanted to include a Leadwerks one but I'm reasonably pleased with results. Here's a screen-shot showing a single Leadwerks mesh, it has multiple LODs and only a base texture has been applied. Specular and normal is available but not created for this test. Ambient occlusion and light mapping was baked in. A material shader for blending detail textures would be a great addition and should be a simple task. Original "Canyon" scene... Little fog and lighting adjustment... Currently the closest output format GROME supports is Collada DAE but the Leadwerks conversion tool dae2fbx doesn't like the input. Need to work on that before I can automate terrain export for Leadwerks. Not a priority since I'm still working on Unity3D scripts for GROME. Large sections of detailed height-maps can be turned into multiple LOD irregular triangle meshes. Easily moved, positioned, swapped in and out for use in a treadmill terrain system. Once the system has been fully scripted for automated export of an entire terrain there are many other small problems to resolve. The native Leadwerks vegetation would need to be handle paging in data for different zones. Lakes and rivers which work like the Leadwerks water plane except it has a plane for each terrain "tile" and has a mask so it doesn't flood an entire height level. Roads are spline based objects, only the level is baked into an exported terrain mesh. A road object mesh for each zone would need to be constructed, possibly with at least 2 lods.
  5. Nice of you to say so Roland. Of course I only use the word cell as reference to an area, a virtual space of n size. If you make the patches small and room height to something like 8 patches then and add vertex noise you get some very lumpy cave like walls, there's plenty of room to experiment.
  6. Offsetting the "world" as you describe Red is a valid technique, it's one way tiled worlds work. What you're wanting to do is add an extra co-ordinate space to everything. World co-ordinates (e.g lat/lon) Tile co-ordinates (e.g. tile[12][13]) camera space co-ordinates (e.g a Vec3() position ) And everything is tied up in a manager to deal with it. Some commercial games exhibit small glitches when crossing these tile co-ordinate boundaries and have to adjust the world. Spatial audio glitches are a clue as the "listener" can lag a little. Sometimes you get rubber-banding in an external view for no apparent reason. Parent everything within tile space to the tile and you move the tile - thus moving everything with it. You'll be able to do this in my procedural dungeon. In the final part I plan to show how you can create infinite dungeons by exploiting "cells" as a virtual co-ordinate system. Currently each wall is parented to the room mesh, move the room and all the lights, props, wall, go with it. Each room lives in a virtual "cell" space. Replace room with terrain tiles and it's similar, if less sophisticated.
  7. About: This is a short series for the Leadwerks community on the process of creating a simple game using procedural content. This week we implement the map creation process discussed in part 02 then add the mesh generation and a controller to fly around our level. Then we'll have the first iteration of our procedurally generated map. Part 01 Part 02 Starting with the Map class. Map:Create Function...first iteration, no corridors. Simple nested for-loop to generate a room for each cell. Each room is stored in the table Map.Room[] with dimensions, a counter for reference and a cell offset in world units. For our example a cell is a virtual 40x40 space, our example map is made of 4 x 4 cells. We call the function like this... Map:Create (407, 4 , 4 , 40 ) And our function definition is... function Map:Create( seed , xsize , ysize , cellscale , roomscale ) self.xsize = xsize self.ysize = ysize self.seed = seed self.roomscale = roomscale math.randomseed( seed ) if roomscale == nil then roomscale = 1.0 end Map.roomscale = roomscale if cellscale == nil then cellscale = 40.0 end Map.cellscale = cellscale Map.roomheight = 2.0 Print("Creating map, dimensions " .. xsize .. " x " .. ysize) -- table to store our rooms Map.Room = {} -- room counter rcount = 1 for x=1,xsize do for y=1,ysize do if math.random() > 0.2 then self.Room[rcount] = {} local r = self.Room[rcount] r.roomID = rcount r.cellx = x r.celly = y r.x = math.random(cellscale) r.y = math.random(cellscale) r.width = math.ceil( math.random(3 , cellscale ) ) r.length = math.ceil( math.random(3 , cellscale ) ) r.info = string.format("id %.2d cellx %.2d celly %.2d x:%.3d y:%.3d w:%d h:%d", r.roomID , r.cellx , r.celly , r.x , r.y , r.width , r.length ) print(r.info) rcount = rcount+1 end end end self:MakeGeometry() end In the above code to reduce rooms arranged in a solid 'grid' there's a random chance that a cell skips room creation. The cell offset ( r.x and r.y ) serves to add more irregularity to the layout. Map.roomscale and Map.cellscale: bigger number = bigger space. One scales distance between rooms, the other scales the room mesh. After generating the geometry from such an arrangement we get this... I've added a head-up display to show an overhead map and annotations to the screenshot to show how the distribution of rooms work. So far so good. Perhaps worth mentioning the CELLS are ordered top to bottom then left to right. That gives you some idea that the random offset works to radically shift rooms around to avoid being too attached to the grid arrangement. Info: CELL is a term I use to describe a container in virtual space. Before we generate any geometry for our rooms we have all the data we need to display a map (like the one above). Debug overlays or HUDs are handy during early development and can be migrated to a finished game HUD later. All we need right now is some way to check room volumes and positioning, some info and the players position. Later we can use a second camera to draw a top-down view if required. Another feature we want in our HUD is some flag to draw it, a position to move it about the screen and a scale so we can fit the map to the whole screen or just squeeze it into a corner. The following code does all this. X and Y is typically used as a screen-coordinate position to draw an element and s is the size in pixels to fit the map into. If you need to re-size text as well then you need to start rendering these to a buffer but we'll avoid the extra complexity. This is often made easier with OpenGL commands but they are not exposed to Leadwerks LUA scripts (as of 2.5). Drawing the HUD and overhead map function DrawHUD() if App.showhud ~= true then return end SetBlend(2) SetColorf(0.1,0.3,0.1,0.3) DrawText("ROOM DATA",22,22) local c = string.format("RoomCount %d", #Map.Room) DrawText(c,22,60) local x = 40 local y = 80 for n,r in pairs(Map.Room) do DrawText( r.info , x , y ) y = y + 16 end x = 400 y = 80 s = 512 sx = s / (Map.cellscale * Map.xsize) sy = s / (Map.cellscale * Map.ysize) DrawText("OVERHEAD MAP",x,y-20) --DrawLine(x,y,x+s,y) DrawLine(x+s,y,x+s,y+s) DrawLine(x+s,y+s,x,y+s) DrawLine(x,y+s,x,y) for n=0,Map.xsize do DrawLine(x + (n*Map.cellscale*sx) , y , x + (n*Map.cellscale*sx) , y + s) end for n=0,Map.ysize do DrawLine(x , y + (n*Map.cellscale*sy) , x + s , y + (n*Map.cellscale*sy)) end -- sorry for the fiddly math here -- its needed to match the map scale with the HUD display scale for n,r in pairs(Map.Room) do local roomx = x + (( r.x + (r.cellx-1)*Map.cellscale) *sx ) local roomy = y + (( r.y + (r.celly-1)*Map.cellscale) *sy ) DrawRect( roomx , roomy , r.width * sx, r.length * sy ) DrawText(string.format("%.2d",r.roomID), roomx + ((r.width*sx)*0.5)-8 , roomy + ((r.length*sx)*0.5)-9 ) end DrawText(string.format("view co-ords x:%d y:%d", camera.position.x , camera.position.z) , 40, GraphicsHeight() - 20 ) -- player marker cross in yellow SetColorf(0.3,0.3,0.1,0.3) DrawText("X", x + (camera.position.x * sx)-4 , y - (camera.position.z * sy) -8 ) SetBlend(0) end The map size is adjusted by changing "s = 512" to however many pixels across. Objects are scaled and drawn accordingly. Once we start merging rooms this will need some alteration, the overhead camera might be a viable alternative and one we can have some fun with. randomly flagged tile data, looks like a "BallBlazer" level. Tiles and Geometry Rather than write up how it works you can look through the code and tinker with it. The next and penultimate part will cover generating corridors and using "tile" data to merge overlapping rooms and add props like doors. You'll see already there are random light sources assigned to each room, random assortments of props such as columns, crates, particles etc. can be done in a similar fashion. The Code for this article I've attached the full code which creates the room data and geometry (sans no corridors and intelligent tile merging - we'll deal with that in part 04). Don't forget to execute this script using ScriptEditor.exe (or run it with ENGINE.EXE) you will need to make sure the path at the top of START.LUA (MediaDir) points to your Leadwerks SDK location and the default scripts are present (as "required" at the top of the script). You'll find a few bits of code commented out and older functions I used to create meshes. I've left them in for curiosity (learning and laughter). Until part 04, have a good weekend.
  8. This is the topic for a small book. All these experiments and more were tested in Patrick Cozzi's book "3D Engine Design for Virtual Globes", the books website has small examples for experimenting with depth precision, camera distances, scale. Just to prove the point you can't have your cake and eat it. I highly recommend this book for anyone seriously interested in the problems of terrain and scale. If you have a cockpit in world space that moves away from the origin (this applies to any 3D engine) you will get vertex jitter. That's it. Obtaining a source code license to try and rebuild the engine for 64bit math is not practical. Both in terms of license cost and ability required - I'm sure Josh uses some arcane matrix shortcuts and it won't be enough simply substituting one type to another. So that's the negative. Now the positive. Your solution would be to render the cockpit it in it's own world space. The one in combat helo never leaves the world origin, sames goes for guns and knives. This is layering. It's no different from pasting old school 2D cockpits over the screen, only difference is the 2D image is a 3D model with lighting. Getting everything to match up, exterior models with interior models, lighting etc.is the hard work. That is the solution for any kind of inventory or vehicle cockpit. It doesn't work so well for exteriors but could be done in a similar fashion. The panacea is to create a tiled/paged environment so the viewer never strays too far from the origin. Think old scrolling tiled games where you can explore maps bigger than the screen. You have a slightly easier time with this in UnityPro, something I'll be covering in a future book. I hope to have a working Unity example ready in time for publication but it's not a trivial thing. You can't apply transformations to Leadwerks Terrain and you can't have more than one Terrain object so you need to build your own system from scratch. But you have to ask yourself if the game justifies it. Really the easiest thing is just make a smaller game and all the problems go away. Battlefield 3 uses art tricks to make you think you're going faster and further than you are but you're still moving around very small areas, even in jet fighters. That's art trickery and a whole topic of the illusion of speed. Here's some more practical help and I don't want to spend more time on this as it really is a never-ending topic. One of the things I did to fudge depth writing on SOME objects to create a second overlay material that was only applied to problem objects (such as rockets inside pods). My MESH.FRAG is far from standard but after the BLOOM conditional I have the following kludge which is applied to an exterior container (eg. rocket pods). // I need the depth offset proportional to the camera distance from the vertex #ifdef LW_OVERLAY2 float dist = length(modelvertex.xyz - cameraposition ) / 512.0; float z = DepthToZPosition(gl_FragCoord.z); z = z - dist; gl_FragDepth = ZPositionToDepth( z ); #endif
  9. Long boring article? What's wrong with those? I'm very good at them.
  10. For helicopter dusting effects we had to rotate the emitter rapidly to get a radius, there's only so many kinds of effects you can get the LE system to do. It's functional but primitive. BTW Daimour I was inspired by your video to add extra debris effects to our explosions. For which I thank you.
  11. Cool thanks. No problem to work around.
  12. A quick question since I search didn't yield much. Are any of the openGL commands exposed to LUA scripts in Leadwerks?
  13. I see you have to plug-in to recharge. Is there something you're not telling us? He's a CYLON!
  14. Bribes are good, for the record I accept paypal or brown paper packets behind the water-tank, third stall, gents toilets, Leeds City station. Thing about "brainstorming" is nothing is wrong. Everything and anything goes. Pretty much what I heard about the gents toilets at Leeds City station.
  15. About: This is a short series for the Leadwerks community on the process of creating a simple game using procedural content. In part 01 we looked at one theory of generating random maps in the style of old school dungeon crawlers. This week we'll put that into practice to generate map data, room geometry and mesh colliders. The easy part was adding a flying physics based camera to act as our first-person flown "spaceship". Again I want to flag I'm not a LUA expert, this is not a LUA tutorial but like most languages they are a syntax away from common functionality. It includes examples and explanations of some LUA code to relate why I did something a certain way. What you see is what you get. All code is freely available for use and modification however you see fit. How to use the code and run any examples in this series After working on the code a short time I found using the Leadwerks ScriptEditor.exe better for the process rather than attempting to run and debug it as an editor script. And one last note before we get on with it, 99% of the assets are included the Leadwerks SDK media folder so please edit the "MediaDir" in the LUA source. Any other required media will be included as a download. Pre-amble over with. Lets get to it. Map Data to 3D Geometry - first experiment The focus for this tutorial is generating map data then creating 3D geometry from it. The latter raised several questions about what would work for a tutorial and flexibility for use in different kinds of games. So I've focused more on this side for part 02. (Also I had to re-write it meaning less time to work on the map data code). My first room generator working prototype created "shoe boxes" as pictured below. With lighting, ambient sounds and the physics on a controller to fly your 'ship' around in first-person view it was a passable bit of code. figure 2.2 - "ShoeBox" room and corridor structure "ShoeBox" was efficient in that it was a collection of flipped volumes with light sources, individually painted surfaces (6 materials) and would be good for a simple iPhone adventure. When it came to merging volumes for more complex rooms I realised there would be a lot of code needed to split up geometry and re-build it. Rather than turn it into an exploration of CSG, triangulation and mesh simplification (which is not trivial) I ditched it for another simpler approach. Going back to how 2D games work, room geometry became a collection of grids (figure 2.2) that can be thought of in terms of traditional 'tiles'. figure 2.2 - tiled room (aka a regular mesh) Looking more like a terrain mesh with walls and roof, the grid structure makes it easier to merge volumes, add doors, corridors and holes traps or vertical shafts. And by increasing the mesh density and adding vertex noise you can turn rooms into caves with bumpy walls. I felt justified in presenting this method as it allows more possibilities and simplifies geometry construction. In appearance it's quite like old-school cells and tiles, similar to existing 2D dungeon map generators. In my working prototype you can't individually paint a tile but it might be possible to modify the code to allow for UV painting and save out this data. Each room can have it's own unique set of materials. LUA code-time. Geometry Construction Leadwerks like other engines provides tools to create solid shapes entirely in code. First you need to create a Mesh object then a Surface object attached to that Mesh. local room = {} room.mesh = CreateMesh() room.surface = CreateSurface(room.mesh) Note: For clarity this is using ONE surface, this will be expanded to use a six surfaces for each side of the room. The important part is that you add geometry to surfaces, you paint surfaces with materials, you create colliders with surfaces. It's all about the surfaces baby. All room elements such as walls, floor, lights, props etc. are parented to the room.mesh which is positioned in world space. Moving the room is as simple as calling Map:Room[id].SetPosition(x,y,z) Really evil dungeon masters might want to re-position a room with players inside. Well you can do that, even rotate it. Parent the room to the whole map (which has a pivot) and you can roll the entire map around for a marble game. All walls are solid but as they are one sided you can see right through them when viewing from outside. Patch Maker Let's look at a LUA code snippet for creating the roof and floor mesh, I want to draw attention to one of the cute things LUA can do and if you've not come across it before it can be confusing. So I draw your attention to it now. The assignment of (nameless) functions to a table and indexing them by string. Depending on what part of the room we are building we take care vertices are wound the correct way and the vertex normals are perpendicular. So I put the AddVertex() and AddTriangle() calls into a table and for ease of identification indexed them by string such as "roof", "floor", "north_wall" (walls not included here for clarity). addvert["floor"] = function (s,x,y,height,xsize,ysize) return s:AddVertex ( Vec3( x-(xsize * 0.5), height , y-(ysize *0.5) ) , Vec3( 0 , 1 , 0 ) , Vec2(x / (ysize*0.1), 1.0- y/(xsize*0.1)) ) end addvert["roof"] = function (s,x,y,height,xsize,ysize) return s:AddVertex ( Vec3( x-(xsize * 0.5), height , y-(ysize *0.5) ) , Vec3( 0 , -1 , 0 ) , Vec2(x / (ysize*0.1), 1.0- y/(xsize*0.1)) ) end addtris["floor"] = function (s,v,ysize) s:AddTriangle ( v-ysize-1, v , v-1 ) s:AddTriangle ( v-ysize-2 , v-ysize-1 , v-1 ) end addtris["roof"] = function (s,v,ysize) s:AddTriangle ( v-1, v , v-ysize-1 ) s:AddTriangle ( v-1 , v-ysize-1 , v-ysize-2 ) end function Map:CreatePatch( surface , width , length , height , mode ) for x=0,width do for y=0,length do vcount = addvert[mode](surface,x,y,height,length,width) -- we degenerate first row and column when making a grid if ((y>0) and (x>0)) then addtris[mode](surface, vcount , length) end end end end Our room geometry code needs to call the patch builder with dimensions and the name of the component like thus... -- example useage from the room builder Map:CreatePatch(room.surface, 8 , 8 , 0 , "floor") Map:CreatePatch(room.surface, 8 , 8 , 2 , "roof") That's the easy part. We will need to extend Map:CreatePatch to take our merged room data and generate an appropriate mesh to fit the irregular shape of our rooms and corridors as supplied by our dungeon creator. Now we have a method to generate basic rooms which is easy to modify we can look at the other problem; creating our random map. Remember the map structure we're looking for, a grid of cells into which we position at random offsets a regular set of rooms (see figure below). Each room being of variable size and can overlap. For this part of the tutorial we're going to keep the rooms small enough to prevent overlap to keep the source size down and reduce the complexity. We'll cover triangulation for a more advanced geometry function in a later part. In other words I couldn't get it to work properly in the time allotted. figure 2.3 - room and corridor structure We'll begin with a creator function... -- function to build entire map -- params: random seed value, xsize and ysize (dimensions of map in cells) -- roomscale (is multiplier of room size in world units) function Map:Create( seed , xsize , ysize , roomscale ) math.randomseed( seed ) if roomscale == nil then roomscale = 1.0 end Map.roomscale = roomscale Map.roomheight = 2.0 Print("Creating map, dimensions " .. xsize .. " x " .. ysize) -- table to store our rooms Map.Rooms = {} ... ... end For our dynamically generated game level, we need to know a couple of things; How big in game cells (how many rooms across and down) The seed from which the random nature of all springs forth (how poetic) How big we want the rooms to be relative to each game cell (room scale). A tile is simply a value stored in a 2D array e.g. tile[x,y] Our data would benefit from being organised into a grid. A 2D tile structure which represents an overhead view of our 3D world. This makes tile arrangement makes it simple to merge rooms and corridors, flag as walls, doors, traps and anything else we might want to generate. However...(c'mon you knew that was coming)... If we want to make really HUGE levels then array mapping will be inefficient, the 400x400 grid in our example will be fine but anything larger will become resource hungry as we increase the world size. Much of it becomes empty space. To avoid unnecessary memory usage and run-time costs we will virtualise the space a little. We've done it already with our room nodes (figure 2.4) figure 2.4 - room nodes are virtualised rooms Note: A room object simply exists at world_x, world_y and is this >< big. This is for boundary test and positioning. We will use a 2D array of tiles for each room. Each tile maps to a room_x, room_y. This way the data is available to game logic for locating objects, spawn points. After room generation is complete we run a post processing function to merge rooms, this is where the tile array comes in handy. The room merge steps through all rooms, a boundary check is performed on neighbours and merging into a new room as needed. Corridors are considered rooms (just thin), where they bend they are in fact two overlapping rooms and should be merged during the same process. After rooms have been merged, the geometry builder works on the new set of room tiles to spit out all the required meshes, lights and props. Infinite Power! In theory we can make an infinite dungeon if we move the rooms around us at the origin and use world space as a random seed for new rooms. An order of magnitude more advanced than Very Big Cave Adventure. 10 PRINT "You are in a cave (N,S,E,W)?" 20 INPUT a$ 30 GOTO 10 Out of time! Yes I've run out of time for part 02 due to code re-writes. I'll write up the room generator code as part 03 and post the example code with it. Then we'll start to see the two halves coming together and creating our procedural maps. Preview: HUD Overhead Map First pass on HUD to show location of rooms (with ID) within the randomly generated map complex.
  16. I'm just happy to throw out functions for whatever is asked (within reasonable time constraints). Happy for Rick to take point, he's got a good head on what's reasonable in scope. If it's a secret ballot then pretend I didn't write that.
  17. Tis true I have some grey hairs now.
  18. Well Roland, thanks to Facebook and Google keeping secrets isn't a problem any more. Even if their data on you is wrong it's the new improved truth Oh brave new world. I was thinking about the whole genre thing, every "man and his dog" (see what I did there? movie reference?) might have a different take on what genre. Being an old film buff I was thinking about giant ants. And really zombies, ants, giant blobs. If you build the game so it can be divorced from content, so a pak loads in the zombies, audio, weapon, video post effects such as contrast, saturation etc. then you can have the same game with a variety of "worst case scenario" adventures. Which is actually a good name for a survival game, "Worst Case Scenario", quick trademark WCS (which could also mean Weapon Control System). I think I'd love to see 50ft giant screeching ants towering over Smalltown USA in mono, then zombies, then 50s style flying saucers. Or even a "Find the Fridge" game where you have a hide and seek (hot and cold scanner) to find the lead lined fridge before the nearby atomic test bomb is detonated. Ah possibilities. Don't mind me. I just love old films.
  19. How about some small and simple to get the hang of the workflow? Maintaining the pace in a long project is hard, really really hard, don't dismiss it, it's on a par with swimming the English channel hard. That's the level of dedication you'll have to face on non-trivial projects. Please see the following "State the obvious" chart Keep it simple: Simple = greater chance of completion Completion = enjoyable <- You want to be here Non-completion = disappointing.
  20. semi real-time is better performance wise. Just render one side of the cube each frame. After 6 frames you've done the whole thing. If you make it small enough and ignore shadows and lighting the performance hit is small. And you don't have to render all the renderables, so to speak. All the functions to do this are already present, it just requires some assembly. Someone posted something in the gallery a while back.
  21. It would be going up this weekend, got some booky stuff to get out of the way before tomorrow. I'm having some code issues with getting the corridor geometry joining with room walls. There's an interesting TSurface.Slice(...) command that's not exposed in LUA which I'm guessing is a helper function in 3D World Studio. That might have been interesting to play with. Put some AI robots in the rooms to shoot at you, add some laser guns and power ups then you're good to go.
  22. About: This is a short series for the Leadwerks community on the process of creating a simple game using procedural content. A short while ago I was approached to write a book on terrain generation using dedicated tools for a variety of game engines. There's a lot more to game content than just terrains. Josh's recent blogs on CSG got me thinking about one of my favourite games and had me itching to re-visit the genre. This series is an exploration of topics I don't normally exercise but are fun to do. Leadwerks is a fun engine that's ideal for prototyping ideas. So throw out your terrain system, we're going to make a game all about claustrophobia. We're going DOWN into the tunnels to blow stuff up Leadwerks style using a mix of old-school gaming know how and modern day 3D. Our goal: create a simple six degrees of freedom shooter set in a procedurally generated network of rooms and corridors. You can use this as the basis for a number of different games but as I'm a fan of the old classic shooter "Descent" and it's easy to create a physics controller to fly around in Leadwerks. Also it can be re-worked using Leadwerks3Ds CSG functions when it's available. Procedural Map Generation Dungeoneering is back in gaming news with Legend of Grimrock, a take on Dungeon Master grid based geometry. Many games are based on grids, they are easy to work with and often form the basis of AI routines. They are also easy to generate geometry for. There have already been numerous articles and blogs on creating such levels, you'll find links at the bottom of this article. True Story: The Survival horror Amiga game Xenomorph copied the same gridded dungeon mechanics in a blatant rip-off of the Alien universe where stone walls were replaced by ship corridors. Coded by an ex-Microprose employee I visited his house somewhere in Devon many years ago. He revealed that many of the game objects I clung onto for dear life had no function whatsoever. Lesson learned: Don't explain everything, keep the mystery, it's dishonest but more fun for the player. But before we look at some LUA code to create geometry we'll first have a taster of different techniques used in creating random level geometry. After that we'll kick things up by adding more vertical elements for our demo game. I warn you in advance, I'm not a LUA expert and nor am I a big fan but I'm sure you good folks can make it better and LUA brings the examples to the widest possible audience. Node based grid Our goal is to create a collection of rooms connected by corridors through which we can explore. A simple approach is to seed a random number of nodes (rooms) and connect them up. There are other methods, such as a corridor based approach which adds rooms in a second pass, such a method is used in the classic DOS game HACK (aka NETHACK). For our examples we'll stick to a 40 x 40 grid to keep it simple. Each grid square could equate 100 world units or 10 in Leadwerks, it doesn't matter as long as we use a consistent scale. We'll stick to 100 units (1 unit = 1 meter) per grid square for this example meaning our potential map is 400x400 units. Here each node represents a room of random size. We can restrict the size of the room to fit within its parent grid to make it easier to deal with problem of overlapping rooms as illustrated in the figure below. Eventually we'll construct the geometry to build these irregular shaped rooms so they merge as a single entity. You can see that choosing the size of rooms will impact on how much corridor space you're going to end up with per map. This is something you can set in code easily giving control over how open or closed your level will feel. If we stick to the grid arrangement connecting them by corridors becomes an easy process. The difficult part is constructing the vertices and triangles to fit together nicely but we'll get to that. By far the easiest way of joining rooms together is by joining them at the cardinal points of the room. While this makes logic easy it also makes for a pretty boring layout. What's more, there's no reason why a corridor has to be of fixed width...or height. A room typically connects to a room in a neighbouring grid using the straightest link possible and we'll dog leg corridors as required. To add some interest we'll create a 'route' through the grid and randomly connect to neighbours. Again there are many ways you can do this and I encourage you to try your own variations. Our rule-set will have a random chance of connecting to a neighbour if that room. That chance will degrade if that room overlaps and on the number of existing corridor links. Hopefully our final 2D layout will approximate the figure below. Then each room can add its own flavour by adding columns, point lights, props, whatever fits your game. Once we've got a class to generate the map we can then move on to generating the required geometry (surfaces) so we end up with something looking like... Things get even more exciting when we'll extend these maps into 3D, with vertically offset rooms and corridors. Eventually we'll have a complete base generated by a single random seed you can fly, shoot, leap, run through with a basic controller. Once we make the logic for generating rooms 'furniture' props can be parented to the room mesh to take advantage of culling. I'm not going to add much in the way of occlusion, instead Leadwerks can take the stain and should do a good job with no effort on our part. In part 2 we'll start with some code to generate the above with geometry directly in the Leadwerks editor and we'll be using Vertex and Surface commands to create rooms which look like the screen-shot below. Random room generation in LUA, corridors coming shortly for part 2 Everyone is welcome to contribute. External Links Procedural Content Wiki http://pcg.wikidot.c...geon-generation Generating Random Dungeons http://dirkkok.wordp...article-series/
  23. Yeah you can probably get away with hiding the mesh but if that doesn't work there's a material "invisible.mat" (and also a frag shader which discards all pixels). Set the object to use this and that will have the desired effect.
  24. Since the ocean effect is written in shader language, does that mean it's below C level? *ouch* stop hitting me
  25. Standard LUA library calls. math.random() -- generates float between 0 and 1 math.random(high) -- generates int 1 to high math.random(low,high) -- generates int value low to high and might want to use... math.randomseed( os.time() ) -- seed for number generator You can look these up (and more) in math section of the LUA documentation which is available at LUA.ORG
×
×
  • Create New...