Wow look, it's January 30 already!
Will I finish and release something tomorrow night?
Here's a current video.
Thursday, January 31, 2013
Wednesday, January 23, 2013
Day 23 - some progress!
I promised myself I would make some progress on my 1GAM a month tonight, so I did!
Nothing terribly exciting, however definitely important for productivity. I finished up my simple 'tagger' so I could tag a node in maya as an "asset root" (so everything under it gets lumped into one addressable asset), as well as being able to specify the material name for meshes in maya. Materials are completely separate from geometry, I just need to call out the name of the material resource. I also made an 'auto-export' button in Maya that just 'Does The Right Thing(tm)'
If you're curious, here's an example of a material data file:
The parameter/texture names here get bound to parameters of the same (string) name called out in whatever shader is used to render the object. This was just some test blend shader I was working on a while ago.
The material calls out the default effect name as "testeffect_col_tex" - however that's not exactly the shader. Within that effect are different shaders for different engine supported features (skinned, lightmapped, skinned+lightmapped, ...). This lets me use the exact same material resource on several different meshes, and the engine can pick the correct actual shader. Some day the different shader variants will be auto-generated, but I'm not there yet.
At some point I'd like to make a blog post just covering my material/shader system. I've iterated on the concepts several times and think I have landed on a very clean and extremely flexible architecture.
The next thing I need to do for the game is implement simple trigger volumes, and make one that triggers level completion when you bump into it.
Nothing terribly exciting, however definitely important for productivity. I finished up my simple 'tagger' so I could tag a node in maya as an "asset root" (so everything under it gets lumped into one addressable asset), as well as being able to specify the material name for meshes in maya. Materials are completely separate from geometry, I just need to call out the name of the material resource. I also made an 'auto-export' button in Maya that just 'Does The Right Thing(tm)'
If you're curious, here's an example of a material data file:
The parameter/texture names here get bound to parameters of the same (string) name called out in whatever shader is used to render the object. This was just some test blend shader I was working on a while ago.
The material calls out the default effect name as "testeffect_col_tex" - however that's not exactly the shader. Within that effect are different shaders for different engine supported features (skinned, lightmapped, skinned+lightmapped, ...). This lets me use the exact same material resource on several different meshes, and the engine can pick the correct actual shader. Some day the different shader variants will be auto-generated, but I'm not there yet.
At some point I'd like to make a blog post just covering my material/shader system. I've iterated on the concepts several times and think I have landed on a very clean and extremely flexible architecture.
The next thing I need to do for the game is implement simple trigger volumes, and make one that triggers level completion when you bump into it.
Thursday, January 17, 2013
Visual Studio and Custom Build Rules
Today I was interested in generating some code. I made an external tool that took an input file (.gen) and output a C++ header (.h) file.
Then, I wanted to make this as painless as possible to set up in VS, so that whenever you added a .gen file to the project, it would automatically know how to build it, track dependencies, etc.
My first attempt was of course the familiar "Custom Build Tool". If you add an unknown file type to a VS project and go to its Properties page, you can build the file with a "Custom Build Tool", then fill out a Command Line to run, etc.
Now, this would totally work. Except it's really tedious to maintain. It must be propagated to every configuration your project builds with. It's a giant painful error-prone way to maintain this sort of thing.
There's a better way. As I understand it, as of VS2010, VS is built on top of MSBuild. There's a set of files (a .props, a .targets, and an .xml file) to create your own "Item Type" that can be selected to build files with.
I'm going to lay out a simple example that worked for me. I don't end up using a .props file in my example as I didn't need it, but presumably you can use that to add your own properties that can be set per file for the build step.
Disclaimer: I don't know if this example is completely minimal - I was just happy to actually get it to work. The documentation for how to set this stuff up is really hard to find and dig through.
First, the .xml file (in my example, codegen.xml).
This is nifty and part of the magic. I don't exactly understand the difference between an ItemType and a ContentType, but here's the pragmatic explanation: given this, when you add a .gen file to your project, it will recognize that file as a "CodegenItem" and associate the build step with it. Which is coming next.
Here's the .targets file (codegen.targets) (because of the use of $(MSBuildThisFileName) in this file, it's important that the file name matches the .xml file, so codegen.xml + codegen.targets)
So the first order of business is to 'include' the .xml file we have above, and associate the ItemType that comes from there ("CodegenItem") to the Target we have below ("GenerateCode").
The target is the actual build step. We give it a name "GenerateCode". Next, the BeforeTargets="ClCompile" attribute says that this build step should be run before the ClCompile step (which is the name of the target of the built in C++ compiler). Because I'm generating code, I want this. Next the Inputs and Outputs ("Identity" is the name of the file the build rule is applied to, and Outputs need to be specified so that VS can understand file dependencies).
I thought the Message entry would actually get displayed when the build step as invoked, however it doesn't. I don't see it output in the Build window, but I left it there because I think it should work. It's possible it's being printed to some log file somewhere. Here is the documentation for it: http://msdn.microsoft.com/en-us/library/6yy0yx8d.aspx
Finally, the Exec task (docs here: http://msdn.microsoft.com/en-us/library/x8zx72cd.aspx) - this specifies the commandline to execute. Straightforward - I have a codegen.bat file that takes the input and output file and does its thing.
Now, I would suggest putting these files alongside your .vcxproj. To actually get this to work, open VS, right-click your project and select Build Customizations... In this window, choose Find Existing... and browse to and select your .targets file. Then check the box to enable it. Now, when you add your files to a project, it will have your custom build step associated.
So, there you have it. Now here's the questions I'm left with:
- How do I refer to the Inputs and Outputs of the Target in the command line? I'd like to say %(Inputs) and %(Outputs). Needing to repeat that is redundant and tedious.
- Why doesn't the Message print in the Build window?
- Where's all the friendly introduction docs to this feature?
Thanks to John Calsbeek for a point in the right direction!
Then, I wanted to make this as painless as possible to set up in VS, so that whenever you added a .gen file to the project, it would automatically know how to build it, track dependencies, etc.
My first attempt was of course the familiar "Custom Build Tool". If you add an unknown file type to a VS project and go to its Properties page, you can build the file with a "Custom Build Tool", then fill out a Command Line to run, etc.
Now, this would totally work. Except it's really tedious to maintain. It must be propagated to every configuration your project builds with. It's a giant painful error-prone way to maintain this sort of thing.
There's a better way. As I understand it, as of VS2010, VS is built on top of MSBuild. There's a set of files (a .props, a .targets, and an .xml file) to create your own "Item Type" that can be selected to build files with.
I'm going to lay out a simple example that worked for me. I don't end up using a .props file in my example as I didn't need it, but presumably you can use that to add your own properties that can be set per file for the build step.
Disclaimer: I don't know if this example is completely minimal - I was just happy to actually get it to work. The documentation for how to set this stuff up is really hard to find and dig through.
First, the .xml file (in my example, codegen.xml).
This is nifty and part of the magic. I don't exactly understand the difference between an ItemType and a ContentType, but here's the pragmatic explanation: given this, when you add a .gen file to your project, it will recognize that file as a "CodegenItem" and associate the build step with it. Which is coming next.
Here's the .targets file (codegen.targets) (because of the use of $(MSBuildThisFileName) in this file, it's important that the file name matches the .xml file, so codegen.xml + codegen.targets)
So the first order of business is to 'include' the .xml file we have above, and associate the ItemType that comes from there ("CodegenItem") to the Target we have below ("GenerateCode").
The target is the actual build step. We give it a name "GenerateCode". Next, the BeforeTargets="ClCompile" attribute says that this build step should be run before the ClCompile step (which is the name of the target of the built in C++ compiler). Because I'm generating code, I want this. Next the Inputs and Outputs ("Identity" is the name of the file the build rule is applied to, and Outputs need to be specified so that VS can understand file dependencies).
I thought the Message entry would actually get displayed when the build step as invoked, however it doesn't. I don't see it output in the Build window, but I left it there because I think it should work. It's possible it's being printed to some log file somewhere. Here is the documentation for it: http://msdn.microsoft.com/en-us/library/6yy0yx8d.aspx
Finally, the Exec task (docs here: http://msdn.microsoft.com/en-us/library/x8zx72cd.aspx) - this specifies the commandline to execute. Straightforward - I have a codegen.bat file that takes the input and output file and does its thing.
Now, I would suggest putting these files alongside your .vcxproj. To actually get this to work, open VS, right-click your project and select Build Customizations... In this window, choose Find Existing... and browse to and select your .targets file. Then check the box to enable it. Now, when you add your files to a project, it will have your custom build step associated.
So, there you have it. Now here's the questions I'm left with:
- How do I refer to the Inputs and Outputs of the Target in the command line? I'd like to say %(Inputs) and %(Outputs). Needing to repeat that is redundant and tedious.
- Why doesn't the Message print in the Build window?
- Where's all the friendly introduction docs to this feature?
Thanks to John Calsbeek for a point in the right direction!
Wednesday, January 16, 2013
Day 16 - I haven't abandoned you!
Yikes, no updates in about a week. I'm finding it difficult to balance work and working on my 1GAM project, so the reality is that I've made almost no progress. I have not abandoned this effort!
My current 'todo' is implementing a simple Maya tool so that I can attach custom metadata to nodes in the scene that get exported with the geometry data.
One such piece of metadata is to be able to tag a transform node as an 'asset root'. When I export a scene from Maya, I currently jumble all of the geometry into the scene into one geometry asset. This gets thrown into an asset pack file, and in the editor I can refer to assets within a pack file with/a/pathname/like/this.asset:some_asset. Tagging a node as an asset root will let me export more than one asset from the same Maya scene. I want this so I can put the physics and visual geometry of a level / object / whatever in the same Maya scene. This is a workflow issue that's just really tedious to manage currently.
The other piece of metadata is the name of the material to apply to the geometry. Currently the Maya exporter exports everything with one of a few different hacked-in materials. I've been manually fixing up the data after it comes out of Maya. Putting the material name on the node will be very helpful, so I can easily change geometry and there's nothing tedious in the way.
So, that's where I'm at. It's a bummer, for sure, but work is my priority. I think I'm only going to reasonably be able to spend time on this during weekends, and I'm not sure if I will finish something by the end of the month. I would very much like to, so that gives me 3 weekends (really only 2, but I'll cheat and say that I can spill into the weekend of Feb2+3).
So, what is the minimal 'todo' to get something playable in 3 weekends?
- get some sort of 'end level' implemented. The current level can easily be considered a maze, so let's say I'll plop down an exit trigger in the level. If you hit it, you beat that level.
- I can very easily churn out let's say 5 levels. Really, I can create a level in Maya, and get it working in game in 5 minutes.
- this COULD be all! in this state, the game is "find your way through the maze". I can package that up and call it good.
"stretch goal" (because kickstarter)
- polish the stomper hazard. In my last post I have the 'todo' to make this feel good. I'll need to implement level restarting (easy!) and then this could be a 2nd point of release. I can plop down a bunch of stompy's in the levels and call it good. Unfortunately I don't have a prefab system yet, so it'll be more than a few minutes to get these scattered in the level, since it's just a handful of components to attach to an object.
Really with the time left, I'm hesitant to reach any further than that. I'm in the home stretch now, so I need to wrap it up.
That said, there's a few different ideas for what to do for February:
- continue working on this game. Implement new hazards, polish it up better, release a v2
- start work on some brand new game idea
- spend some time doing engine tech (few things I could use immediately: prefab system, rotate+scale gizmos, undo)
My current 'todo' is implementing a simple Maya tool so that I can attach custom metadata to nodes in the scene that get exported with the geometry data.
One such piece of metadata is to be able to tag a transform node as an 'asset root'. When I export a scene from Maya, I currently jumble all of the geometry into the scene into one geometry asset. This gets thrown into an asset pack file, and in the editor I can refer to assets within a pack file with/a/pathname/like/this.asset:some_asset. Tagging a node as an asset root will let me export more than one asset from the same Maya scene. I want this so I can put the physics and visual geometry of a level / object / whatever in the same Maya scene. This is a workflow issue that's just really tedious to manage currently.
The other piece of metadata is the name of the material to apply to the geometry. Currently the Maya exporter exports everything with one of a few different hacked-in materials. I've been manually fixing up the data after it comes out of Maya. Putting the material name on the node will be very helpful, so I can easily change geometry and there's nothing tedious in the way.
So, that's where I'm at. It's a bummer, for sure, but work is my priority. I think I'm only going to reasonably be able to spend time on this during weekends, and I'm not sure if I will finish something by the end of the month. I would very much like to, so that gives me 3 weekends (really only 2, but I'll cheat and say that I can spill into the weekend of Feb2+3).
So, what is the minimal 'todo' to get something playable in 3 weekends?
- get some sort of 'end level' implemented. The current level can easily be considered a maze, so let's say I'll plop down an exit trigger in the level. If you hit it, you beat that level.
- I can very easily churn out let's say 5 levels. Really, I can create a level in Maya, and get it working in game in 5 minutes.
- this COULD be all! in this state, the game is "find your way through the maze". I can package that up and call it good.
"stretch goal" (because kickstarter)
- polish the stomper hazard. In my last post I have the 'todo' to make this feel good. I'll need to implement level restarting (easy!) and then this could be a 2nd point of release. I can plop down a bunch of stompy's in the levels and call it good. Unfortunately I don't have a prefab system yet, so it'll be more than a few minutes to get these scattered in the level, since it's just a handful of components to attach to an object.
Really with the time left, I'm hesitant to reach any further than that. I'm in the home stretch now, so I need to wrap it up.
That said, there's a few different ideas for what to do for February:
- continue working on this game. Implement new hazards, polish it up better, release a v2
- start work on some brand new game idea
- spend some time doing engine tech (few things I could use immediately: prefab system, rotate+scale gizmos, undo)
Wednesday, January 9, 2013
Day 10 - (alive || dead)
10 days already? Geez. So technically I'm 1/3 done with this game. I'd would say I'm not in terrible shape, except I know the unknowns will prove me wrong.
Tonight I made my stompy spike object deadly. I was able to attach a physics primitive that gets moved appropriately, and added collision tests to that vs the ships in the game (of which there is 1). If they collide, the ship is marked 'dead' and attached to the spikes. The idea here is to have the spikes impale the ship, and kill input so you feel helplessly stuck as your ship carcass gets smashed by spikes.
I've re-purposed the light shining down to show when the ship is alive/dead, for debugging. Green light = alive, red light = dead :)
To polish this up the physics shape on the spikes will need to be adjusted (from a sphere to a box), and the ship should be attached by projecting the ship position onto the spike plane, and raising it off by the ship radius. Then, tighten the physics geometry so there isn't a noticeable 'pop' when the transition happens. Or, even better, kill the input (so the ship is 'dead'), and don't do a rigid attachment until the spikes 'move into' the ship and the ship is a certain distance from the spike plane. This latter solution will look best - you get killed, which freezes you in place, then I can have the spikes look like they impale you until the ship reaches the bottom of the spikes, then you get stuck to it.
Additionally, the far extent of the spikes should be limited to the ship's radius so you don't intersect the opposing wall. To polish this up, keep the current behavior (so it penetrates the wall as it does now) - *unless* there is a ship attached, in which case don't penetrate the wall all the way. That will make it look super slick.
Also, I think the camera will need a little bit of jiggle in this state - being attached to the spikes gives a pretty jarring camera movement - if the camera is a little looser/springy, that can make it feel better.
I'm hesitating to show it to you without the slickness implemented, but in the interest of fully documenting my progress and possibly teaching someone out there something, I'll show what it looks like right now (horrible) so maybe you can appreciate the work game devs do to make games awesome :)
Tonight I made my stompy spike object deadly. I was able to attach a physics primitive that gets moved appropriately, and added collision tests to that vs the ships in the game (of which there is 1). If they collide, the ship is marked 'dead' and attached to the spikes. The idea here is to have the spikes impale the ship, and kill input so you feel helplessly stuck as your ship carcass gets smashed by spikes.
I've re-purposed the light shining down to show when the ship is alive/dead, for debugging. Green light = alive, red light = dead :)
To polish this up the physics shape on the spikes will need to be adjusted (from a sphere to a box), and the ship should be attached by projecting the ship position onto the spike plane, and raising it off by the ship radius. Then, tighten the physics geometry so there isn't a noticeable 'pop' when the transition happens. Or, even better, kill the input (so the ship is 'dead'), and don't do a rigid attachment until the spikes 'move into' the ship and the ship is a certain distance from the spike plane. This latter solution will look best - you get killed, which freezes you in place, then I can have the spikes look like they impale you until the ship reaches the bottom of the spikes, then you get stuck to it.
Additionally, the far extent of the spikes should be limited to the ship's radius so you don't intersect the opposing wall. To polish this up, keep the current behavior (so it penetrates the wall as it does now) - *unless* there is a ship attached, in which case don't penetrate the wall all the way. That will make it look super slick.
Also, I think the camera will need a little bit of jiggle in this state - being attached to the spikes gives a pretty jarring camera movement - if the camera is a little looser/springy, that can make it feel better.
I'm hesitating to show it to you without the slickness implemented, but in the interest of fully documenting my progress and possibly teaching someone out there something, I'll show what it looks like right now (horrible) so maybe you can appreciate the work game devs do to make games awesome :)
Tuesday, January 8, 2013
Day 9 - break
No progress today, took a break from all the coding :)
Next to do is to make stompy lethal, so attaching some physics to him that can kill the player.
Day 8 - meet stompy
I've decided to take a new direction with the game. It's no longer multiplayer since I'm not going to have the time to work with other people to iterate on the balancing.
I'm also not interested in tackling AI for my first month project, so I'm not intending to have enemies roam the map and hunt you down.
Instead, meet Stompy. He's not as harmful as he looks (yet!)
On the tech side, last night I implemented spotlights. I had an idea for doing really simple realtime indirect lighting, but I decided because the camera is top-down and there is no floor in the level, it might not be that noticeable. I might still try it if time permits.
Also, I added a way for GameObject components to have a GameObject* member, and specify an object name from the level in the editor, and at run time the pointer would get filled in if the name is valid. It doesn't clear this pointer if the object goes away just yet, so care must be used!
I suspect progress to slow down a bit as I'm done with Christmas vacation and back at work, coding all day!
I'm also not interested in tackling AI for my first month project, so I'm not intending to have enemies roam the map and hunt you down.
Instead, meet Stompy. He's not as harmful as he looks (yet!)
On the tech side, last night I implemented spotlights. I had an idea for doing really simple realtime indirect lighting, but I decided because the camera is top-down and there is no floor in the level, it might not be that noticeable. I might still try it if time permits.
Also, I added a way for GameObject components to have a GameObject* member, and specify an object name from the level in the editor, and at run time the pointer would get filled in if the name is valid. It doesn't clear this pointer if the object goes away just yet, so care must be used!
I suspect progress to slow down a bit as I'm done with Christmas vacation and back at work, coding all day!
Sunday, January 6, 2013
Day 7 - lighting the way
Spent some of today experimenting around with the art a bit.
- Made a much bigger level and locked the camera to the player
- Turned the perspective camera back on so you can see the walls a bit
- Added dynamic lights to the ship and every bullet (My thought is each ship will have a different color, and cast a light of that color)
-- My engine only supports point lights currently. I'll have to implement spotlights as I'd like to see what it looks like with a spotlight only in the direction the ship is traveling
- Got rid of the ugly brown :) made the level geometry pure white
I also set the background father back in the world so you get some parallax effect with it in the background. I definitely want to put a few more layers in between there with stuff so you get more parallax.
This is pretty minimalistic art aside from the background effect, which I expect I'll iterate on some time. This is feeling a bit better to me.
- Made a much bigger level and locked the camera to the player
- Turned the perspective camera back on so you can see the walls a bit
- Added dynamic lights to the ship and every bullet (My thought is each ship will have a different color, and cast a light of that color)
-- My engine only supports point lights currently. I'll have to implement spotlights as I'd like to see what it looks like with a spotlight only in the direction the ship is traveling
- Got rid of the ugly brown :) made the level geometry pure white
I also set the background father back in the world so you get some parallax effect with it in the background. I definitely want to put a few more layers in between there with stuff so you get more parallax.
This is pretty minimalistic art aside from the background effect, which I expect I'll iterate on some time. This is feeling a bit better to me.
Day 6 - biting the bullet
Not a big update for today. I spent some time working on my collision handling - I implemented the swept sphere vs line segment to see if that would fix everything. It made things better, but didn't catch all cases, and I saw some cases of the sphere flying off the level plane - meaning it caught a collision with one of the diagonal triangle edges.
So, I spent the evening integrating the Bullet physics engine. After a bunch of tweaking, things work!
...For the most part. I am not at all happy with how the bullets are bouncing off of the walls. Often they will bounce tangent to the surface! They are sphere rigid bodies, and both the bullet and level geometry have a restitution of 1.0. I'm also using the CCD motion in Bullet to avoid tunneling. So, I'm not sure what's up. Guess I'll have to tinker with it.
...I really need to get going with implementing gameplay!!
So, I spent the evening integrating the Bullet physics engine. After a bunch of tweaking, things work!
...For the most part. I am not at all happy with how the bullets are bouncing off of the walls. Often they will bounce tangent to the surface! They are sphere rigid bodies, and both the bullet and level geometry have a restitution of 1.0. I'm also using the CCD motion in Bullet to avoid tunneling. So, I'm not sure what's up. Guess I'll have to tinker with it.
...I really need to get going with implementing gameplay!!
Saturday, January 5, 2013
Day 5 - editor improvement
I spent much of the day today in airports getting back home to Seattle after being away for the holidays. I did manage to squeeze some code time in on the airplane, so I made an editor improvement I've been wanting to make.
When the editor shows the Inspector window for a GameObject, it naturally queries the engine for a list of components on the GameObject. For each component type, the engine has registered a bunch of metadata about the data members of the component. This is used to serialize and deserialize the components from json without needing to write any code other than registering the members with the metadata system (one line of code per member), and having some free functions set up that take types (like ints, floats, strings, vector<T>s, Materials, etc) and serialize/deserialize them to json. For complex types like vector<T> and Material, the serialize/deserialize functions end up calling serialize/deserialize on the inner objects, which use the same metadata system, and so on.
So when the editor goes to build the UI for inspecting a component, we ask the engine to serialize each member of the component type to json. We also have a string representing the type of the component member, which is stored in the engine's metadata. So we might get back something like "translation", which is a "vec3", and a fragment of json that looks like "[0.99205, 0.0531423, -0.533324]".
Up until today I simply made a single textbox and pasted the json text directly into it. When you would edit the text, I would parse the json and feed it back through the whole system so that it would set the new data on the object.
Tonight I took advantage of the component type, the "vec3" information above, and stood up a little infrastructure so I can register C# control types with this type string (if there is nothing registered I fall back to the textbox-of-json). The only ones I managed to complete on the flight were handling "float", and "vec3". Float does the easy thing - a textbox with the value in it. For vec3 I do something barely more complicated - a WPF Grid with three textboxes, one for X, Y, and Z.
However this will finally let me get around to writing the gui for editing material properties, which is why I was laying this groundwork. "Material" is one of the types the system recognizes, and there will be a rich gui control for tweaking the material parameters for an object.
Below is a screenshot of the editor showing the improvement. It's not flashy right now, but it's really important. This image reminds me I still need to do something to get the property name column to be the same size.
When the editor shows the Inspector window for a GameObject, it naturally queries the engine for a list of components on the GameObject. For each component type, the engine has registered a bunch of metadata about the data members of the component. This is used to serialize and deserialize the components from json without needing to write any code other than registering the members with the metadata system (one line of code per member), and having some free functions set up that take types (like ints, floats, strings, vector<T>s, Materials, etc) and serialize/deserialize them to json. For complex types like vector<T> and Material, the serialize/deserialize functions end up calling serialize/deserialize on the inner objects, which use the same metadata system, and so on.
So when the editor goes to build the UI for inspecting a component, we ask the engine to serialize each member of the component type to json. We also have a string representing the type of the component member, which is stored in the engine's metadata. So we might get back something like "translation", which is a "vec3", and a fragment of json that looks like "[0.99205, 0.0531423, -0.533324]".
Up until today I simply made a single textbox and pasted the json text directly into it. When you would edit the text, I would parse the json and feed it back through the whole system so that it would set the new data on the object.
Tonight I took advantage of the component type, the "vec3" information above, and stood up a little infrastructure so I can register C# control types with this type string (if there is nothing registered I fall back to the textbox-of-json). The only ones I managed to complete on the flight were handling "float", and "vec3". Float does the easy thing - a textbox with the value in it. For vec3 I do something barely more complicated - a WPF Grid with three textboxes, one for X, Y, and Z.
However this will finally let me get around to writing the gui for editing material properties, which is why I was laying this groundwork. "Material" is one of the types the system recognizes, and there will be a rich gui control for tweaking the material parameters for an object.
Below is a screenshot of the editor showing the improvement. It's not flashy right now, but it's really important. This image reminds me I still need to do something to get the property name column to be the same size.
Friday, January 4, 2013
Day 4 - banging against the wall
So I still haven't spent any time on figuring out the art style. Tonight I worked on collision.
The level geometry I have is a triangle soup created from Maya. This isn't the easiest thing to check collisions against - and in fact I've never written collision detection routines, so I only had a little bit of idea of the problems I would run up against. I'm quite sure that making the environment out of OBBs would be simpler, but out of curiosity I left it as is so I could work through it and discover the problems myself.
What I had going yesterday was simple raycasting. Every frame, when the ship moves, I calculated a 'distance to move this frame', and casted a ray from the current position to my next desired position (based on my velocity vector) into the triangle soup and see if I hit any triangles. If I did, I would calculate the rebound effect. I did this recursively until the 'distance to move this frame' was zero. (This recursive processing handles the case when you run into a corner and end up bouncing off of 2 walls in 1 frame)
So I knew the raycasting was naive, and tonight tried to replaced it with casting a swept sphere instead of a simple ray. The idea here was to combat the precision issues I had with the ray casting (if you were close to a wall you could nudge yourself through the wall), as well as give a proper volume to the ship (if you check the previous video, you'll see the ship penetrates walls until the point at the center of the ship hits the wall).
I worked through the math for sweeping a sphere against a plane (which I'm confident I did correctly), however I ran into a fairly major problem that I didn't originally anticipate. I'm still able to penetrate walls. The collision detection code finds the point on the triangle plane that you're intersecting, and then tests that point to see if it actually lies within the triangle. This test fails at the edges of triangles, so the edge is able to penetrate the sphere. Thinking about this, it's not as simple as also detecting collision against the triangle edges, since the walls are two triangles, I think I'm really going to have to solve the penetration problem correctly like a real physics engine. Not something I'm interested in spending much more time on this month. Instead, I would simply plug in a physics engine (Box2D or more likely Bullet) and call it good.
Another option is to make the level environment simpler - I could make the levels tile based, and then I would do a proper 2D collision detection against straight boxes. I'm pretty confident doing a swept circle against a grid like this would leave me with robust collision. I'm not sold on a tile based level, and even if I do I might just plug in Box2D with it and try doing it myself later. I have to keep in mind the primary goal here is to get a *shippable* game by the end of the month, and plugging in an existing robust physics engine mitigates the risk of spending lots of time on my own collision routines. It is something I'd like to work out myself at some point, though.
I'm leaning towards plugging in Box2D. I'll think on it.
No pics/videos of the game for today - the game essentially looks the same as yesterday. Instead, here's a cat, because internet and physics.
The level geometry I have is a triangle soup created from Maya. This isn't the easiest thing to check collisions against - and in fact I've never written collision detection routines, so I only had a little bit of idea of the problems I would run up against. I'm quite sure that making the environment out of OBBs would be simpler, but out of curiosity I left it as is so I could work through it and discover the problems myself.
What I had going yesterday was simple raycasting. Every frame, when the ship moves, I calculated a 'distance to move this frame', and casted a ray from the current position to my next desired position (based on my velocity vector) into the triangle soup and see if I hit any triangles. If I did, I would calculate the rebound effect. I did this recursively until the 'distance to move this frame' was zero. (This recursive processing handles the case when you run into a corner and end up bouncing off of 2 walls in 1 frame)
So I knew the raycasting was naive, and tonight tried to replaced it with casting a swept sphere instead of a simple ray. The idea here was to combat the precision issues I had with the ray casting (if you were close to a wall you could nudge yourself through the wall), as well as give a proper volume to the ship (if you check the previous video, you'll see the ship penetrates walls until the point at the center of the ship hits the wall).
I worked through the math for sweeping a sphere against a plane (which I'm confident I did correctly), however I ran into a fairly major problem that I didn't originally anticipate. I'm still able to penetrate walls. The collision detection code finds the point on the triangle plane that you're intersecting, and then tests that point to see if it actually lies within the triangle. This test fails at the edges of triangles, so the edge is able to penetrate the sphere. Thinking about this, it's not as simple as also detecting collision against the triangle edges, since the walls are two triangles, I think I'm really going to have to solve the penetration problem correctly like a real physics engine. Not something I'm interested in spending much more time on this month. Instead, I would simply plug in a physics engine (Box2D or more likely Bullet) and call it good.
Another option is to make the level environment simpler - I could make the levels tile based, and then I would do a proper 2D collision detection against straight boxes. I'm pretty confident doing a swept circle against a grid like this would leave me with robust collision. I'm not sold on a tile based level, and even if I do I might just plug in Box2D with it and try doing it myself later. I have to keep in mind the primary goal here is to get a *shippable* game by the end of the month, and plugging in an existing robust physics engine mitigates the risk of spending lots of time on my own collision routines. It is something I'd like to work out myself at some point, though.
I'm leaning towards plugging in Box2D. I'll think on it.
No pics/videos of the game for today - the game essentially looks the same as yesterday. Instead, here's a cat, because internet and physics.
Wednesday, January 2, 2013
workflow improvements
Here's some workflow improvements I can choose to tackle at some point to make development go more smoothly:
Maya
- need 'auto-export' button that just does the right thing, so I can easily iterate on geometry
- need a way of assigning material name to geometry
Editor
- undo (unlikely to happen soon)
- Save (instead of Save As - this is just a few lines of code)
- rotate+scale gizmos
- ability to rearrange GO hierarchy in outliner
Game
- hot reload assets (this is actually already implemented, but I need some kind of GUI to actually trigger it)
-- hook up simple http server and spit out resource pages with buttons to reload each resource?
Maya
- need 'auto-export' button that just does the right thing, so I can easily iterate on geometry
- need a way of assigning material name to geometry
Editor
- undo (unlikely to happen soon)
- Save (instead of Save As - this is just a few lines of code)
- rotate+scale gizmos
- ability to rearrange GO hierarchy in outliner
Game
- hot reload assets (this is actually already implemented, but I need some kind of GUI to actually trigger it)
-- hook up simple http server and spit out resource pages with buttons to reload each resource?
Day 3 - balls + walls
I noticed yesterday's post got about 200 views - awesome! Thanks for checking my stuff out :)
Today I worked on shooting and collision.
I also changed the camera view to orthographic. I'm not sure how I feel about this yet. I want to go back and try a perspective view with a shorter FOV so there's not *much* distortion at the edges of the screen, but I think I do want some. Maybe. I can certainly make the environment "look 3d" in a few different ways, but I think being able to see the environment with some perspective distortion would be handy.
I also got multiple controllers working, I think. I don't have a second controller handy so I can't test it, but you can assign a controller index to a ship, so I suspect it works.
The collision routine is as simple as it gets - for movement, raycast against the level geometry and respond accordingly. You can certainly break it if you move slowly into a wall, and I've seen bullets fly through walls. I *think* this is only due to precision errors, so I need to add a little epsilon so when you cast a ray, the ray 'backs up' by an epsilon before doing the raycast. Hopefully that makes it rock solid, but it's possible I'm missing something.
Actually, I think it would be better to move away from a raycast to a swept-sphere test. This will build in a rather large epsilon (the sphere radius), and will solve the problem I have of the ship/bullets clipping into walls until their center point hits. So I just need a swept sphere vs triangle intersection test, and I should be good to go. I won't have ChristerE's book handy until the weekend, so I might just try to derive it myself.
At this point I've actually completed everything on my 'initial todo' list. For the rest of the night I'd like to browse google images for reference art, to figure out some kind of style for the game. I like the abstract nonsense I wrote in the background shader, but I was also thinking of maybe doing something gadgety (I guess steam punk ish), but that would be pretty demanding on art requirements. I've had a couple artist friends offer to help, but I don't want to rely on that too heavily, especially for my first game where things are still very uncertain. I'm not even sure how many hours per week I'll be able to dedicate once I get back from Christmas break and get back to work. So, maybe gadgety for a future game.
So here's my current TODO list:
- iterate on art style
- build a next TODO list for gameplay
Today I worked on shooting and collision.
I also changed the camera view to orthographic. I'm not sure how I feel about this yet. I want to go back and try a perspective view with a shorter FOV so there's not *much* distortion at the edges of the screen, but I think I do want some. Maybe. I can certainly make the environment "look 3d" in a few different ways, but I think being able to see the environment with some perspective distortion would be handy.
I also got multiple controllers working, I think. I don't have a second controller handy so I can't test it, but you can assign a controller index to a ship, so I suspect it works.
The collision routine is as simple as it gets - for movement, raycast against the level geometry and respond accordingly. You can certainly break it if you move slowly into a wall, and I've seen bullets fly through walls. I *think* this is only due to precision errors, so I need to add a little epsilon so when you cast a ray, the ray 'backs up' by an epsilon before doing the raycast. Hopefully that makes it rock solid, but it's possible I'm missing something.
Actually, I think it would be better to move away from a raycast to a swept-sphere test. This will build in a rather large epsilon (the sphere radius), and will solve the problem I have of the ship/bullets clipping into walls until their center point hits. So I just need a swept sphere vs triangle intersection test, and I should be good to go. I won't have ChristerE's book handy until the weekend, so I might just try to derive it myself.
At this point I've actually completed everything on my 'initial todo' list. For the rest of the night I'd like to browse google images for reference art, to figure out some kind of style for the game. I like the abstract nonsense I wrote in the background shader, but I was also thinking of maybe doing something gadgety (I guess steam punk ish), but that would be pretty demanding on art requirements. I've had a couple artist friends offer to help, but I don't want to rely on that too heavily, especially for my first game where things are still very uncertain. I'm not even sure how many hours per week I'll be able to dedicate once I get back from Christmas break and get back to work. So, maybe gadgety for a future game.
So here's my current TODO list:
- iterate on art style
- build a next TODO list for gameplay
Tuesday, January 1, 2013
Day 2 - something shiny
Day two working on SpaceShooter, my OneGameAMonth entry for January.
My goal for today was to get very basic ship movement in. The left analog stick applies acceleration, and the ship responds. It's also locked to a [-1,1] game grid. Pretty straightforward, and it works pretty well. Next up for ship movement is getting it to bounce off of walls - I'll code it up to bounce off of the edge of the game grid first, then I'll see about adding obstacles. It might be easier if the game board is made of square tiles - I'll just keep that in mind and see what happens.
Aside from that I had to do some engine housecleaning. I extended my Component system so it now supports inheritance. This was needed because I now have a PrimitiveMesh and a StaticMesh component, and there was special-case code in the renderer to draw either of these. Now these both inherit from a base Mesh component which has a virtual GetMeshes() function, so the renderer can pick out the meshes to draw from the component. 1990s style programming 101 stuff :)
Then I spent a few hours messing with shaders. You can check them out in the video below. There's no method, it's just madness. Clamp things, rotate things, distort textures, multiply by masks, etc. Jumble it all together and you see what I've got.
So, day 2 success!
My goal for today was to get very basic ship movement in. The left analog stick applies acceleration, and the ship responds. It's also locked to a [-1,1] game grid. Pretty straightforward, and it works pretty well. Next up for ship movement is getting it to bounce off of walls - I'll code it up to bounce off of the edge of the game grid first, then I'll see about adding obstacles. It might be easier if the game board is made of square tiles - I'll just keep that in mind and see what happens.
Aside from that I had to do some engine housecleaning. I extended my Component system so it now supports inheritance. This was needed because I now have a PrimitiveMesh and a StaticMesh component, and there was special-case code in the renderer to draw either of these. Now these both inherit from a base Mesh component which has a virtual GetMeshes() function, so the renderer can pick out the meshes to draw from the component. 1990s style programming 101 stuff :)
Then I spent a few hours messing with shaders. You can check them out in the video below. There's no method, it's just madness. Clamp things, rotate things, distort textures, multiply by masks, etc. Jumble it all together and you see what I've got.
So, day 2 success!
Subscribe to:
Posts (Atom)