Jump to content

Flexman

Members
  • Posts

    916
  • Joined

  • Last visited

Blog Entries posted by Flexman

  1. Flexman
    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.
  2. Flexman
    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.
  3. Flexman
    Today I added a postbuffer pixel shader to do light amplification for ETADS. Based on Geeks3D lightamp shader and modified for Leadwerks Engine it actually performs amplification by sampling the source pixel and if it's below a threshold, boosts the pixel intensity. Pretty neat.
     
    These are tests, the left half is the amplified area, right side is ambient light.
     




    The the first greyscale image has the polarity reversed. Into the mix I added a scanline mask with animated noise. The ETADS mask looks pretty good although I'm using a 'scope' mask here which more interesting visually.
     
    The last shot shows more of the noise distortion that makes the image 'buzz'. This is almost ready to drop into the TADS class.
     
    As for thermal imaging, we would need to add heatmaps as secondary UVs or fake it using some heat lookup. This is adding a level of complexity I don't want to pursue at this time as we could spend years throwing in tiny amounts of detail most gamers are not going to need.
     
    This amplification shader allows us to give some threshold and boost control to the gunner so they can apply some measure of skill in finding ground units visually in poor lighting conditions.
     
    *edit*
     
    After some consideration I think some attention to thermal signatures would be good after-all. This could be done by adding an "objectname_intensity.dds" map to texture channel 4 or 5. Then modify the base Leadwerks pixel shader to boost the intensity of the pixel from that channel. It shouldn't be too hard to take an existing diffuse texture map, desaturate and reduce the brightness to almost nothing then airbrush in some intensity levels.
     
    This would work well with the light-amplification post processing shader too.
     
    Source
  4. Flexman
    Spending time working on my laptop here, which now has some reliable memory from Kingston has proved to be a fantastic little work platform for developing with Leadwerks.
     
    The FFD or Free flight dynamics physics engine is still a little rough around the edges for putting into Combat-Helo proper so I'm working on a small test platform which hooks into the Leadwerks entity update callback and calls the FFD update.
     
    I'm not sure if this is a good method of doing it, FFD is just a flight model and doesn't handle ground collisions. Originally intended for Microsoft Flight Simulator it releases control when the object is on the ground. Which serves me well, switching over to Newton physics at that point.
     
    I've been going through correcting some type assignments and now the FFD engine seems to be working except for some unexplained force in one direction so I'll have to go through it with Fred and see if we can't find out what's up with that.
     
    Thanks for all the offers and suggestions with regard to my dead motherboard (it truly was gone).
     
    Source
  5. Flexman
    Spac3Rat sent in a nice new game icon as well as two editions of his Rotorwash magazine from 2006 to read. Fascinating look at building helos for FSX, one thing we learned about FSX models, they don't work too well for our kind of real-time work. But fascinating all the same.
     
    Dave is busy in 3DMAX building something that looks very much like a Chinook. I'm making incremental improvements to the GUI system, panels can now be roughly dragged around without risk of "mouse droppings" (the window/item being dropped off the mouse during aggressive mousing). Buttons and input fields are getting focus and their classes respond to events OK. Running two Combat-Helo instances side by side isn't recommended but doable, solves the logistics problem for network testing until I can persuade my wife to maybe set-up a virtual machine with 3D acceleration like she has on her desktop.
     
    The gui system is linked list of active TGUIPanels (base type) which maintain their own linked list of user controls (TGUIItem), each control having a simple drawing function. They keep track of what's got focus, what's been clicked on and dragged around. It's only going to be used for a few things but it makes it easier to add checklists if needed. And they just make use of a couple of base textures and existing game fonts (of which there are about 5).
     
    The IHADSS or HMD has a problem that has been bugging for some time since the early flight tests and a recent personal message confirmed it. Look over your shoulder and how the hell can you tell which way up you are when the artificial horizon vanishes? So we're going to fix that to work as it should as soon as we can. It's also supposed to be quite low resolution but that would look really ugly when it's constantly in your face, I can't bring myself to reduce it to VGA res.
     
    Dave has learned that Chinooks are round, very round. I learned how to pronounce it correctly (Shin-uk) thanks to my Canadian wife who repeatedly laughed at my attempts.
     
    Finally, Red Dead Redpemtion has been a fantastic game, the open-world and amoral nature of Grand Theft Auto games applied to the old West (USA, 1903 era) fits perfectly. And you get to play a protagonist you can like. Amazing inverse kinematic system meaning character movement seems quite natural compared to traditional baked animations. A world that is just fun to roam around in, a magnificent achievement. I spent an hour in a saloon just playing Blackjack. Which reminds me, I'm out of Whiskey.
     
    Source
  6. Flexman
    We finally sourced a a reasonably good infantry soldier, low poly model, rigged, animated and exported. We can fill the screen with dozens of these guys, falling, shooting prone, grenade tossing. We'll give them a couple of weapons they can swap between and a range of helmets swapped in by setting an entity key.
     

     
    To initially test animation sequences I populated a drop-down control for the editor dialog with the following LUA, chopped up for readability. But lets you pick which frames to loop by name (or number). This is quite compact for AI troops which need to be lightweight in processing terms, this means non-use of character controllers.
     
     
     
    class.anim = {
    {"Idle",0,49},
    {"Stand and Fire",50,89},
    {"Running",90,111},
    {"Walking",112,147},
    {"Grenade Throw",148,187},
    {"Take Cover",188,213},
    {"Stand to Squat",214,241},
    {"Fire from Squat",242,291},
    {"Squat to Stand",292,313},
    {"Go Prone",314,359},
    {"Fire from Prone",360,379},
    {"Stand Up",380,425},
    {"Death Forwards",426,532},
    {"Death Backwards",533,568},
    {"Jump",569,614}
    }
     
     
    function class:InitDialog(grid)
    local choices = ""
    local total = table.getn(class.anim)
     
     
    for i=1,total do
    choices = choices .. class.anim[1]
    if (i < total) then
    choices = choices ..","
    end
    end
     
     
    self.super:InitDialog(grid)
    group=grid:AddGroup("Animation")
    group:AddProperty("sequence",PROPERTY_CHOICE, choices , "Animation")
    group:Expand(1)
    end
     
     
     
    function object:SetKey(key,value)
    if key=="sequence" then
    object.framestart = class.anim[value+1][2]
    object.frameend = class.anim[value+1][3]
    end
    return self.super:SetKey(key,value)
    end
     
     

     
     
     
     

     
    Source
  7. Flexman
    On the whole, I'm starting to warm to using text for user options, the nineties style. Dave showed me some icon screenshots from ArmA and remembered why I didn't like them. Is that a steering wheel? Desk fan?
     
    Below is an in-game shot showing the menu and data displays for helicopters. Not unlike something you might have seen in older games using pre-rendered art. All interactive objects around the base will have these. If you don't want the floaty status text, CTRL L (for labels) is your friend.
     
    Eventually each helo flight will pull it's call-signs from a datafile (Twodogs, Ugly, Badman, Goody etc.) which will go in placed to the current auto-generated ID. Status refers to the ground crews work time to prepare the helo for it's next sortie. Fuelling and weaponeering.
     
    The play process is typically pick-mission, go to aircraft, pick weapons if default not to liking, hit the fly button. It's been the same in games from Wing Commander to Black Shark. Pretty much universal. And we don't want to break that. Reading how UK operations conduct Apache helicopter turnaround, the Apache lands, is guided into an arming bay and re-armed immediately so it's ready for the next flight whenever that may be. No hanging around waiting for a bird to be armed if you're urgently needed in a support action.
     
    To facilitate this into the traditional game flow, brief>arm>fly, the ground crew servicing timer starts after landing and shutdown. But as the player may change weapons seconds before flight and we don't want to delay, we'll let the players arming choice count as the arming done after landing. With a realism option in to have "Real-time arming" for sim pilots who love to thrash themselves with birch-twigs - metaphorically speaking.
     



     
    Source
  8. Flexman
    I was thinking over some official forum posts and one gentleman indicated that they were partly colour-blind. Accessibility issues are something I think about whenever I'm writing software or web site design work so I kicked myself when I didn't apply that to the interface. I added some GUI elements that link current selection to the tooltip, this should avoid ambiguity in the menu system.
     



     
    So that's all working as it should, just have to fix up the weapon selection system which will be based loosely around this mock-up...



    We has some debate about walking around in ground mode clicking on weapons displayed on the ground like in the above picture. Or some other mechanism involving a fixed camera that cycles through each pylon and a vertical list to choose from.
     
    On the whole, there's not much difference in workload, both are fairly trivial to implement. It's become a style choice. But I'm torn between traditional as above, or flashy console panning cam and up/down list.
     
    Either way it's a far cry from Gunship 2000...or is it?



    Which method will I implement? Stay tuned for the next thrilling blog post when all will be revealed.
     
    Source
  9. Flexman
    Dexsoft's Middle East City pack has been tweaked by the Dave-9000 supercomputer and has produced a low poly high density city block of 1038 polys. Requiring heavy edits of UV co-ordinates and placing all the textures onto a single surface for blinding performance.
     
    Perfect for iPhone and as a building block of the high-density city of Herat.
     

     
    Source
  10. Flexman
    AD has started some great work on the armaments of the CH47 that will form the first major DLC pack for the full release of Combat-Helo. Each door position will offer a fun interactive activity, usually in the form of throwing out obscene amounts of virtual lead.


     

    For more pictures please see:
    ADs SimHQ CH-47 blog update thread

    Mini-gun, I don't get the mini part though.

     
    Source
  11. Flexman
    Periodically I'll create a debug build to see if any OpenGL errors popup and sure enough one did. Tthe MFD buffer mip-maps are created after rendering the contents with a call to buffer.GetColorBuffer().GenMipMaps()
     
    Not much had changed except some additional meshes, animations, all the specular maps, actually quite a lot of material changes to the interior and exterior this past week. But the debug ran fine after building and running it on the laptop. My desktop wasn't having any of it.
     
    EF2000, EECH Enemy Engaged Comanche Hokum and others, not working right? Please update your drivers. So what did I fail to do on my desktop that I did recently on the laptop (due to installing a Windows 7 upgrade). Yup, update my drivers. And lo, all is now well and good.
     
    The moral is, always heed ones own advice. Check your drivers.
     
    Still a little curious as to what was wrong with mipmaps in those drivers. I wonder how well auto-generation of mipmaps are supported across cards and is there a safer way to test it?
     
    Source
  12. Flexman
    Dave, the kids must have been playing "pilot" again, they've gone and pulled off the knob for the standby instrument lighting, make it like the other two rotaries. I'll fix the camera clipping on the seat
     

     
    Source
  13. Flexman
    It's a sentence I pulled out of context from the recent Unity newsletter. It relates to a Mobile Generation Education Project, a project with a $250k giveaway to help students become the mobile innovators of tomorrow.
     
    Now, when I was a student, we didn't have mobile phones, or the world wide web. And if we did, we'd have moved onto something else by now. Teachers point out that 60% of the jobs their students end up doing haven't been invented yet. I helped develop Risk Assessment software used by Walmart among others, five years later it's old technology. Everything moves so fast in this information age and it's accelerating.
     
    I wonder how much of this social web technology that is perceived to have permanence will be around in ten years or even five. I'm starting to see an effect that could be best described as Dawinism applied to digital data, a process of selection that results in the useful data being retained (at least higher up the search tree) and copied. And this process snowballing with an ever increasing amount of new data.
     
    With amazing concepts of collective information gathering such as Seadragon and Photosynth on the horizon, any guesses as to what the future holds in information mining are just that. If you don't know what Photosynth is then check the link and prepare to have your mind blown by possibilities of this and other forms of data.
     
    It doesn't take academics to come up with these kinds of ways of looking at data, it takes a creative (and ever so clever) mind. Picasso said everyone is born an artist until it's taught out of them.
     
    Right, that killed 10 minutes. I wonder if anyone will be referencing this blog entry when I'm gone from this world. I expect the URLs will have long since died
     
    Source
  14. Flexman
    While waiting on fixes for the flight-model and control inputs, putting some game into the game we talked about ranges and how performance measuring was going to work. In addition we wanted to add a little variety which required working mob AI.
     
     
    So nothing fancy but I managed to rustle up a simple finite state machine FSM to get some tanks and cars running around. Our design uses a group formation system (a group is a number of individual units that share common logic, e.g a tank platoon) and if you've ever used Missioneer you'll be familiar with the concept.
     
     
    Currently tanks are driving around a small test tool I'm using to test the module, switching formations, revving engines, exhaust smoke. Performance is king so updates are interlaced, no vehicle physics are required so animation suffices.
     
     
     



    Each group member has a goal pivot, when the formation changes the individual vehicles seek their pilot according to their driving behaviour. All the pivots are parented to a master pivot controlled by the group. This way you just need to update the group position (e.g movement orders to x/y) and the rest takes care of itself.
     
    We can look into expanding the states later when we want them to do more complicated things, and do that on a per unit basis. Tank gunners will want to turret to target when attacking, manpads will simply turn to face. Same state but slightly different logic per unit. And this can be done in LUA level by setting the models "fsm_mode" key. That makes less work for me and gives Dave the artist some nice toys to play with. At the end of the day I at least have a tile based tank engine to play with. I'll throw up a video.
     
    For the gunnery range we don't need anything demanding; some AI road following traffic, people in groups and the odd vehicle following a set of waypoints. Nothing spectacular or difficult there. That hardest part is turning the 3D geometry of the road network into a navigation grid. Then your mob groups need to know if they are supposed to be following the road or their own formation (switching as they move from one to the other).
     
     
    Roads
     
    The one problem I have in getting AI traffic running around is putting together a nav-grid I can work with. Our roads are large models (2 or 3 assorted) that are built in 3D Max using a height deformation modifier (the same height-map used to build terrain layers). And it mostly fits. I think we need to flatten it out so only the surface triangles can be read and turned into usable data.
     
    Speaking of art, "Mossie" has been given some love.
     
     



     
    Further reading:
    FSM gate scandal - Why they are old hat
     
     

     
    Source
  15. Flexman
    Today was spent working on reliable interface network client/server connections. It's apparent I need to add some additional items to the top of the screen:
     

    Current world time Mission Time (as offset of world time) Connection status indicators (connecting/connected/ping status)
    These to sit alongside the current game mode, camera mode and have a suitable background image.
     
    Testing is proving difficult logistically. I would like a fairly inexpensive second PC with small form factor capable of running the Leadwerks engine at a reasonable speed. Something that can sit on top of/or next to my main PC.
     
    Password protection seems to work with servers rejecting connections appropriately.
     
     
    Facebook
     
    I'm told everyone and their app has a Facebook page so here is the Combat-Helo Facebook entry. There is something of a virtual Apache walk-around with an internal one coming later, a collection of screen-shots in the galleries so you don't have to hunt around for them.

     
    Source
  16. Flexman
    Our Apache received more love today, the cockpit panel textures suffered a little from DDS compression acne. But by increasing the bits-per-pixel to 24 and using DXT1, we get better quality results using a texture half the size as a larger one using 8bpp compressed. And smaller texture memory footprint too. This only works for some textures.
     
    Additionally specular maps were added to the cockpit, now it reacts to light in a much more dynamic way and the scratched glass blast shield and canopy really adds to the sense of enclosure in a cockpit space.
     
    A few major systems are not currently fitted to our Apache, the TADS (or ETADS) was initially removed due to rendering problems. I've re-instated the TADS class and rewrote the rendering function. It's still quite primitive and there's post0processing to add to the tads_buffer as well as overlaying the symbology. As expected the performance hit is around 20% when drawing at full frame-rate. I'll add a frame-skip value to adjust performance for users. The good news is that it's not worse that I thought it would be plus there's still lots I can do to improve performance.
     
    The ETADS display is using the same Fullbright shader as the other MPDs so it's a little overbright. When I'm done it should look the part.
     
    Over the test-map testing the TADS camera.
     
    Rest of the week might be a little quiet as we're rushing to complete the startup and caution/warning system to go with it (keep getting side-tracked and doing other things). The dual-seat multiplayer mode throws up some interesting logic problems with the messaging system when generated messages don't have a source. It has resulted in front-seat controls sending signals to back-seat controls which in turn trigger front-seat controls and so on. This is why messages have a source ID so remote control messages don't trigger a local message transmission thus continuing the cycle. Yes, all I need is a message filter.
     
    Little update***
     


     
    You have control.
     
    Source
  17. Flexman
    Completed changes to the HUD section of the config file.
    <HUD col="1.0, 0.8, 0.2" glow="0" shadow="1" breakoutfpi="1" />
     
    I'm using the TinyXML lib for config functions, it's been fast efficient and easy to use. I added a new option today that was born out of looking at videos of games projected onto huge screens giving almost 1:1 scale. Before my tripplehead PC went pop I had a problem with virtual symbology relative to HUD size. The larger the screen, the smaller the HUD relatively. At it's worst, the effect was looking through a keyhole.
     
    So I removed the keyhole, the "breakout" option in the HUD config will plot some indicators outside the HMD area and in a relative scale to the screen size. This makes it more useful at the expense of not being totally accurate, hence the option.
     
    In the screenshot below you'll note the user colour option for the HUD symbology in effect alongside the flightpath indicator outside the HUD buffer (right of the altitude bar in the hilly bits). This is easier to use on a laptop too where screens are not as bright and it's easier to pick up.
     

     
    There's been an intermittent windows exception error when launching the game (release build). I tracked this down to the old controller config loading which uses IO streams to pull in a data-file. Something is going on there. I need to re-do the controller settings anyway using XML to store response curves and other tweaks you can't do right now. Just a pain as laptop drives are a touch on the slow side.
     
    Source
  18. Flexman
    First of all, a sincere thanks for the feedback. It's not something to get too hung up about and it's easy to get the idea that we spend hours and hours on making HUDs pretty colours without getting anything else done. Yesterday was pretty intensive in terms of tweaks and adjustments to the HUD but not just in terms of colours.
     
    We've added clipping regions (using glScissor() ) so items like the pitch ladder no longer intrude into areas it shouldn't, this declutters and improves overall readability. Also the acceleration cues are no longer available on the CRUISE mode symbology, again reducing clutter.
     
    And the biggest headache which I'll come to in detail has been the flight path vector, that little circle with the stokes at 3, 9 and 12 o'clock. It presented a problem I hadn't anticipated. It's also difficult to explain but I'll try and sum it up.
     
    The idea is that the FPV is drawn in the the direction you're moving, so if you are moving directly forwards it's in front of you. If you are performing a perfect sideways slip to the left, if you turned your head to look along your left shoulder you would see the marker in front of you.
     
    The HMD or HUD represents a 30x40 degree field of view. However, the default field of view for the main 3D view at a resolution of 1024x768 is 90 degrees. The HUDs default scale is 512x512 and would need to map virtual symbols to a 45 degree field of view (512 being half of this example full screen resolution).
     
    Now, if you have a much larger screen resolution, say with a super-wide monitor, or tripplehead (worst case) you're horizontal resolution can be around 3840 pixels across, the game FOV might be 120' and therefore to match the 3D world, the HUD symbology has a field of view as little as 16 degrees. That's tiny.
     
    The result would have the flight path marker moving the HUD really quickly since it covers a smaller relative area. This would suck if you really needed it.
     
    You can't scale the HUD to match the screen resolution as you loose the top and bottom off the screen. Well, answers on a postcard please. Chewing this one over.
     
    Source
  19. Flexman
    Just a short post since I'm busy being pulled in a dozen different directions; I got roped into helping someone create a short health and safety film, drafting a project proposal, raising finances and even managed to fix a long standing bug in Combat-Helo. Now the sensors, line of sight and all that guff is now WORKING again, Hooray. A quick background on that, an engine update needed to fix some occlusion issues slightly changed the Model hierarchy in a subtle way that changed how actual filenames of models were retrieved, long story short, they no longer matched the ones in the vehicle database as they had "lod1" suffixed to everything . But hey it was a quick fix once traced, I digress as usual.
     
    Talented Paolo, creator of many a fine mascot has been working on some fictional nose-art and patches for the squad mascot in Combat-Helo. We knew we wanted it to feature a mosquito, the mosquito is the nickname allegedly given to the AH-64D by Taliban forces. Incidentally it was also the aircraft my father was attached to during World War II so I felt it had a double meaning.
     
    The character will be visible on squad patches and eventually be available as nose-art.
     
    "Mossie" copyright 2012 Paolo Pomes
    Below is an earlier draft of "Mossie" to help decide on nose style, the nose later became the Apache's signature Bushmaster cannon.
     
     



    Please post your thoughts and comments on "mossie", suggestions for what he can hold in his left hand are invited.

     
    Source
  20. Flexman
    All actions relating to the AH64D go though a message receiver. Player mount, dismount, ground crew arming, lights, AI commanding and (getting to the point) virtual cockpit interactions.
     
    The MPD button naming convention of "MPD_1_17" refering to MPD 1 (pilot left) and key 17 (counting from top left) that gets sent to the input handler for that MPD.
     
    Key messages can originate from the client or network. I had to add a source ID to account for situations where one person in the same vehicle has authority over some function.
     
    The keys and knobs are all working well, interacting with the avionics. I've removed some of the more obscure items and checking authenticity of some elements. Had to simplify a few things just because it's not intuitive. CTRL-G (default mapping) will switch to guns. ALT-G cycles gun round burst mode between 10, 20, 50, 100 and full. Burst is the number of chain gun rounds fired with each trigger pull.
     
    MODE is the method of gun tracking. It cycles between
     

    HMD (helmet mounted display, this is TrackIR or mouselook, where you are looking) FXD is fixed forward TADS is the current TADS position.
    This is a fairly important mode distinction, particually in co-op play as the pilot controls gun/rockets and the the co-pilot/gunner operates TADS and other weapons such as the AGMs (air to ground missiles).
     
    This I think neatly simplifies operation and easy to understand. For most situations you will want to leave it in TADS mode so you can quickly deploy cannon or AGMs against ground targets.
     
    MAN RNG adjusts the ballistics trajectory. Cycles between fixed ranges given in meters. It's there for completeness without adding complexity. It's a candidate for removal.
     
    AGM sub mode coming next unless something really cool happens
     
    Source
  21. Flexman
    Before I code the address book, what do you think of this arrangement?
     
    I'm trying to keep interface items as simple as possible as I hate coding fiddly bits. But these things are mandatory for modern multi-player games.
     
    Source
  22. Flexman
    While I'm spending hours pouring over interfacing the flight model, AD has been tinkering with billboards again, finding a blend of shadows. There's still more to do, I want a ground fog layer, multiple layers, realistic light scattering and a more dynamic LOD system which we can't do yet. AD is reducing the tree poly counts from 1,500 to 500 on the LOD1s. This should improve shadow performance a little.
     

    Looking at shadows again, I came across a GameDev.net post that I might look into. It's similar to the shadow system used in Brano's Outerra whole world engine. I'm not sure what it would do to a high bandwidth environment like a 3 monitor wide system. Probably no worse that using HDR or other post-processing effect.
     
    Source
  23. Flexman
    It was over a year ago we were notified that some of the models we had purchased from Dexsoft might possibly have been stolen. After a period of investigation the probability was quite high this was the case and Dexsoft contacted customers to offer new packs. However months later I was unable to get a reply about these replacements and only in November when doing a review of outstanding assets and licensing we had to either press again or do a re-build.


     

    Dave elected to take it upon himself to do a rebuild and not wanting to have to reposition every building adopted the same dimensions with the exception of adding much needed 'basements' (a basement is just an extrusion of the exterior wall so that it will sink under terrain so no gaps are left if the centre of the model is positioned on uneven ground.


     

    Originally the models were made for use in first-person games and LOD0 had details such as railings and girders. Dave completely built (from scratch) versions complete with new textures and made them more efficient at the cost of some detail. An original building had 5213 polygons, after a rebuild only 728 polys (which is iPhone territory).


     



    Original stolen model on left, rebuilt from scratch on right
    Scratch build on left, original on rightAny small indie developer takes a leap of faith when purchasing models from 3rd parties, you don't know where they came from or their history. In this instance we got bitten as did the 3rd party which handled the situation well (but it would have been nice to have the replacements anyway). No harm was done, anyone using or releasing games with 3rd party content be aware.
     
    Thanks Dave for once again being on the ball.
     
     
    Update
    Started work on the updater again.This is based in part on the Leadwerks SDK downloader which is pretty much everything I needed given a little twist and a slice of lemon. Hopefully some of you will be seeing this in the near future. At some point we'll add user names and a regcode system prior to any content downloads (these will not be required to play).
     
    As much as you might want to click on it, you can't yet
    With any luck the 'one click' update system will let us add rolling improvements at the cost of occasionally annoying you with a download when an update is available. I just want to be able to push one button, get the latest changes to any content I own and go.
     
    Support for different builds (content)

     
    Source
  24. Flexman
    Finally a video showing the free flight mode we really wanted to show at Summer Sim 2010. Thanks AD for doing an amazing job of making it all look good.
     
     

    http://www.youtube.com/watch?v=Y6ILqIQDaio
     
     
    Sorry about the lack of blade-cam, LUA object reference problem. Will get it sorted.
  25. Flexman
    Another disaster strikes, PC wont boot at all. Strange thing happens on the BIOS screen, the moment any attempt to detect any drives (and I tried a few different drives that I know were fine), a bright underscore character appears under the circled comma (picture above).
     
    So apart from my laptop I'm now without a working PC and no means to fix it atm :/
     
    Source
×
×
  • Create New...