<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://bphelpsdev.spaces.live.com/mmm2008-07-24_12.50/rsspretty.aspx?rssquery=en-US;http%3a%2f%2fbphelpsdev.spaces.live.com%2fcategory%2fSXE%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Bryan's space: SXE</title><description /><link>http://bphelpsdev.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&amp;_c=BlogPart&amp;partqs=catSXE</link><language>en-US</language><pubDate>Thu, 24 Jul 2008 02:54:41 GMT</pubDate><lastBuildDate>Thu, 24 Jul 2008 02:54:41 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><cf:parentRSS>http://bphelpsdev.spaces.live.com/blog/feed.rss</cf:parentRSS><live:type>blogcategory</live:type><live:identity><live:id>6928811135990455328</live:id><live:alias>bphelpsdev</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>More UI stuff and unit testing</title><link>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!196.entry</link><description>&lt;div&gt;I've made a lot of progress today on the UI plus an in-game unit testing application. I've been able to resolve a lot of the challenges I was having with the UI - vertical scrollbars now work and are easy to add to controls. The textbox now supports selection properly and handles newline characters, the combo box works, the tree view works, etc. It's been a long haul to get this stuff working but hopefully it'll pay off - i'll be excited to release it down the road! I'm working on a PropertyGrid-like control right now (thats only read only, for now) that I think would be very useful for testing, as well as a write-enabled version that might work great for a level editor type application.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;One key feature of my engine that I am excited about is unit testing support, in-engine. I'm a big fan of using test cases to verify code. I like test driven development but don't follow it all the time - I don't think it is ALWAYS appropriate to write test cases first - i think sometimes you need to start designing an idea first to wrap your head around how it should be used, but I'm sure there are people that disagree with me. That being said, I can see cases where starting with a test case is advantageous as it allows you to see how you want the class to work externally, and then focus on the internals down the road. In addition, test cases are awesome for validating code, when you've done major changes or serious refactoring, and want to make sure it still &amp;quot;works&amp;quot;. Its amazing how bugs can propagate like you would not expect.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I've used NUnit pretty extensively, had experiencec with JUnit, and a few other testing frameworks. For C# development, I used NUnit, which I am very impressed with. However, if you have tried to use NUnit to run test cases on your game code, you would probably be disappointed. Trying to get a GraphicsDevice up and running in NUnit is a pain (at least it was for me), and that is necessary to have to make sure code works. For example, I wouldn't be able to test my TextBox without a GraphicsDevice, because I would not be able to instiate it, simply because there would be no way to load the graphical content. Sure, there are ways around this, but most of them mean extra work.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;My solution, then, is to create an in-engine unit test framework. The functionality will be similar to NUnit, in that it scans the assembly for test cases, and then runs them. It is actually up and running right now. It is not nearly as sophisticated or as advanced as NUnit, but as features are needed, they can always be added. The code is pretty simply and utilizes reflection (C# rocks) to find the test setup/teardown/cases.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Also, if you've had experience games, you'll quickly realize that unit tests aren't the end all solution. Can you really write a unit test to see if your bloom feature works? Can you write a unit test that tests that the scene looks the way you want? It could be difficult, sure, for the bloom, you could maybe send in a simple Texture, have it run the post-screen shader, and then verify the results manually, but this wouldn't be an effective test, as it may not translate well to the whole scene. How can you test if a box renders to the screen ok? Do you verify each pixel manually? This would be infeasible and a waste of time. I don't have a great solution for this, but I have some ideas that I hope might make the development process easier. First, in addition to simple unit tests, i will support &amp;quot;Graphical Unit Tests&amp;quot;.  These test cases are actually the kind of test cases i usually program into my project (and that are shown in Benjamin Nitschke's book), where you simply have a test case that does something, and you examine the results manually. This works pretty well, its nice to develop a new feature in a test case and then incorporate it into the game when it is ready. However, once you have the results the way you like, there is no way to automatically verify (regression test it) in the future. My idea is to take a snapshot of the graphical unit test, save it, and then when regressing the graphical tests, the snapshot would be compared with the output, and given a certain pixel tolerance (ie, 95% of pixels must match), and the graphical unit test would let you see the results. This would only be useful for regression testing, as you would have to manually take the &amp;quot;correct&amp;quot; snapshot, so it would have to be correct at some point in time. The nice thing, though, is this would protect you from breaking code. For example, if you mess up the render pipeline and turn off the depth buffer at the wrong time, this should catch it early before leading you on a frustrating search for why your render code no longer works properly.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Anyway, thats it for now, heres a screenshot of the ingame unit test UI:&lt;/div&gt;
&lt;div&gt;&lt;a href="http://byfiles.storage.live.com/y1pXAEZpZ-26McSq-lBvY7fRI3Ivplq240-2bAYoXo9oh2y-PR6UkFFyTmIZry62GYCCjOs7D69zqo" target="_blank"&gt;&lt;img height=200 alt="unit_test" src="http://byfiles.storage.live.com/y1pXAEZpZ-26McSq-lBvY7fRI3Ivplq240-2bAYoXo9oh2y-PR6UkFFyTmIZry62GYCCjOs7D69zqo" width=257&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=6928811135990455328&amp;page=RSS%3a+More+UI+stuff+and+unit+testing&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=bphelpsdev.spaces.live.com&amp;amp;GT1=bphelpsdev"&gt;</description><comments>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!196.entry#comment</comments><guid isPermaLink="true">http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!196.entry</guid><pubDate>Sat, 03 May 2008 03:35:21 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://bphelpsdev.spaces.live.com/blog/cns!602815048C7B5C20!196/comments/feed.rss</wfw:commentRss><wfw:comment>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!196.entry#comment</wfw:comment><dcterms:modified>2008-05-03T03:36:21Z</dcterms:modified></item><item><title>UI revamp in SXE</title><link>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!182.entry</link><description>&lt;div&gt;I decided to rewrite the user interface code from the engine in Shattered Metal to the new UI in SXE. I've gotten a decent amount of experiencing now in writing a UI framework, and each time my attempts have gotten more and more ambitious and I've learned a lot on the way.&lt;/div&gt;
&lt;div&gt;&lt;br&gt;In my first game, PsyOps, the UI code was pretty rudimentary. There was a game screen class and a button class, and that was about it. I did see the value in abstracting away functionality, as it was easy to add a checkbox class later on.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Fields of Chaos featured a much more complicated UI, which is surprising because the entire game was developed in 5 weeks - including the UI code. However it featured multiple button types, like a Color button with colors that fade in and out, as well as a button that had the 3 image states. There were also a lot more complicated controls in Fields of Chaos - there was a tab control, which was pretty easy to implement, and a ListBox control, which was definitely the hardest. I had a crappy implementation the first time around on the ListBox, and the second time around, it worked a lot better. The ListBox was used in both the &amp;quot;Find a Server&amp;quot; screen and for the in-game scoreboard panel. It actually turned out to work pretty well. The flexibility of it was shown when I was able to code up network &amp;amp; performance debugging panels within 15 minutes.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;WiiMotion featured a similar UI structure to Fields of Chaos. Most of the UI code was simply ported over ,and then cleaned up and improved. WiiMotion did feature a few new ideas - for example, in all my previous UI elements, the elements were stretched to fit. This is cool sometimes but not for things like forms with borders - it looks bad if you have different sized forms with a stretched background. Thus, I designed a panel called a UIBorderPanel, which kept the borders at a fixed size and then stretched the interior of the image, so you could get &amp;quot;real GUI&amp;quot; elements. Also, I designed a special panel that would render objects in 3d and use those. This wasn't featured in Shattered Metal, but it is how the characters are displayed in my WiiSnowball game.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;So why the change of pace, if these other UI systems worked ok? Well, one major problem I had was I decided, for ease of use, to make all the coordinate systems &amp;quot;relative&amp;quot; - instead of using pixels as locations, I used the positions 0.0f - 1.0f. So 0.0f, 0.0f was the top left of the screen, and 1.0f,1.0f was the bottom right. I thought this was a great idea because it would allow resolution independence.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Unfortunately, thats the not the case - you could get in situations where you would get rounding errors, and for items like the UIBorderPanel, that needed per-pixel placement of objects, you coudn't guarantee that with the relative coordinates. So my BorderPanel would have overlaps or gaps in it if you scaled it in weird ways - which was bad news. I decided also to model my UI system after the C# GUI class hierarchy, and upon examination, I realized they used per pixel coordinates as well - so thats what I decided to with the SX engine's UI library.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;In addition, I didn't realize the value of having a stack of GameScreens until the engine developed for WiiMotion. My implementation was weak, however, in the fact that I didn't have a good way to accomplish transition effects between GameScreens. It might not seem like a big deal, but as far as polish goes, it is important to have a nice transition between your game screens. I have not started coding the GameScreen class for the SX engine, but it will likely render to a rendertarget, so that you can easily transition between the screens.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Also, in the SX engine, I'm planning on having a Forms-like interface as well. I had kind of a ghetto console in Wiimotion that was not very sophisticated. I want to have a console more like the Source engine, with a form you move around, and a textbox with autocomplete - so that is kind of my goal.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;I also want to support more controls like a TreeView control or something similar...&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;One other thing that is important and that i haven't solved yet is how to deal with multiple controllers interacting with the UI. Input abstraction is a big deal in the SX engine - so it shouldn't matter to the UI whether you are interacting with a gamepad, or a mouse, (obviously you can't type with a gamepad). However, I haven't quite solved the issue of how to handle multiple cursors on screen. In addition, I still haven't solved the issue of exactly how I want to propagate UI events. Currently, each UI element queries the mouse (which needs to be abstracted) for its position and button state. The problem with this is, if you have two forms on top of each other, items in both forms can receive the event. Thus, I was considering having a message-passing event system, where when an event gets generated, it gets sent to each form/element, and the form/element returns if it handled it or not. If it handled it, its all good, otherwise, it'll continue propagating until someone handles it or each element has seen it and refused... I'm not sure what the best way is yet, I'm going to keep brainstorming.&lt;/div&gt;
&lt;div&gt; &lt;/div&gt;
&lt;div&gt;Here's an early early peek at my test program today:&lt;/div&gt;
&lt;div&gt;&lt;a href="http://byfiles.storage.live.com/y1pXAEZpZ-26Mfa8YyIvYZpe8LTkDqort6Wh1EcSZV4_79Yg60nvNFGLAfExCfZNvigfWYoDInb4Zc" target="_blank"&gt;&lt;img height=200 alt="sxe_UI_revamp" src="http://byfiles.storage.live.com/y1pXAEZpZ-26Mfa8YyIvYZpe8LTkDqort6Wh1EcSZV4_79Yg60nvNFGLAfExCfZNvigfWYoDInb4Zc" width=257&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=6928811135990455328&amp;page=RSS%3a+UI+revamp+in+SXE&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=bphelpsdev.spaces.live.com&amp;amp;GT1=bphelpsdev"&gt;</description><comments>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!182.entry#comment</comments><guid isPermaLink="true">http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!182.entry</guid><pubDate>Sun, 20 Apr 2008 01:09:05 GMT</pubDate><slash:comments>0</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://bphelpsdev.spaces.live.com/blog/cns!602815048C7B5C20!182/comments/feed.rss</wfw:commentRss><wfw:comment>http://bphelpsdev.spaces.live.com/Blog/cns!602815048C7B5C20!182.entry#comment</wfw:comment><dcterms:modified>2008-04-20T01:09:05Z</dcterms:modified></item></channel></rss>