Friday, December 06, 2013
THE ASSET PIPELINE EDITOR - PART 1
So, what is this tool? To answer it, let's travel through time to a point, say, four years ago or so.
To make the long story short, during the golden age of XNA I was in the search of an efficient way to replace the built-in content manager class with my own. So I created my own version of this class, but I was still using XNA's content pipeline.
Then, when MSFT announced that they would stop any development on the XNA Framework, like many of you, I remained captive of Visual Studio 2010 IDE for building xnb's. During this year, I decided not to wait any longer for miracles and start building my own content-pipeline replacement.
Let's face it! How many of you have been lately crying out loud for XNA 5? Or asking where the content pipeline has gone? You still need VS2010 to use the content pipeline if you want to use XNA, Monogame or ANX. And no definitive solution has been provided yet. And even if there is something in the works, is it worth for teams?
Be honest here. You guys know that the in game development a content pipeline is indeed needed, but why sticking to a particular IDE for programmers (like VS) or any other programming IDE in the first place? It could make sense for programmers only, but for teams, artists, or even for solo devs that want to have an independent process, it does not. In fact, it could turn out to be cumbersome.
So, that is why I developed the APE. To replace XNA's content pipeline "in spirit" (since it has key deifferences) for those inhouse projects where I wasn't using Unity, UDK or any other authorware with its own content management features.
I must admit that at first I wasn't expecting to get these results, since I was aiming lower, but as times went by, I realize that -and please allow me to say it- I was creating something really good. So I went on until I said "Wow!".
Now, about its key features:
1. Its not for XNA, only: it works for any kind of custom content, not only xnb's. In fact, if you have your own way to manage content when programming a game or provide solutions (like WaveEngine, for instance), you can use it safely since the tool ends its job when the asset its build and copy to the folder you indicate.
2. It's a highly customizable tool: not only you can tweak the editor to meet the needs for your project (to some extent, of course) but also you can define your own building process: import, process, format, writing. You dream of it. You got it.
3. It eases the task of managing game content: that's it, throughout the whole development process. If say, you just want to use the input files as is, like pngs, jpegs, and so on so forth, without any processing, you can because the editor comes with pass-through units. So you can still use the tool to manage which content goes where, even if there is no processing required.
4. It's independent from any programming IDE: this is heaven for artists! If you are a solo programmer working on a game, having to use VS to build content is fine, but when you're woring on a team with artists this is not good at all. The APE comes with a GUI of its own.
5. Test before you promote units: "why is my custom processor not working?". Say bye-bye to these kind of questions since you can test your custom "units" (as I call them) before using them with the editor. Indeed. You can build your own testing assembly for your custom content/process. And once you give it a green light you plug it to the editor as an add-on.
Here you can see the main editor as of today:
The areas indicated in the picture above are the following:
1. Solution Tree: create a solution, add a project for a platform, and you will be able to traverse all the nodes here. Projects can have two or more containers: self, default and partial. And you can add as many folders as you want to each container. In future parts I post more details about this.
2. Search Tool: if you need to see specific nodes of the tree this is a quick way to do it. It works recuresively over the last search, so you can go on reducing results until you find what you want.
3. Output Settings: for every "raw file" that you want to import, you can define how to process it and format it. And for each project, you can define how to write ("export") assets to disk. These are powerful tabs. More about them later ...
4. Build Tool: here is where you decide whether to build assets for the whole solution (all projects) or for a specific project; and also where you define the compilation profile: debug, release, test, ... you name it ... add the ones you need for the solution. You will be able to watch it on a how-to video, later.
5. Configuration Tabs: so far there are four: general settings, solution settings, project settings and container settings. Basically, you can tweak many properties there and even add/remove entries for platforms, profiles, default importers, default writers, to mention just a few. In a later post I will cover all settings.
6. Log Panel: classic in any respectable IDE; here is where the editor informs you about the state of a given process, whether it succeeds or fails, warnings, exceptions. The usual stuff. It's a real friend to understand what's going on. There is more to it than meets the eye, and that deserves another post.
7. Bars and shortcuts: well, this is not indicated in the picture above, but of course that you have menu items (both, as text and buttons) and key shortcuts for many features. Not to mention, contex menues, where applicable, for example to copy or move content. Ahhh, yes! I almost forget it, drag and drop is allowed.
I don't want to go beyond the scope of this post, but I cannot help adding the following picture:
Above there's an example of a test assembly. When you create your units for a specific type of asset- by the way, using C#, this is where you debug them and see whether everything works as expected. Add break points, switch over text, find offending code!
And finally, for this post: "previewers". When you traverse the solution tree and select a raw file (or source file), the editor shows information about the file as well as a previewer for it. By default, the APE comes with previewers for some image, audio and video formats. Or else it will switch to an icon previewer. But the good news is that if you need to preview more formats you can create your own previewers! What is more, you can replace all built-in ones if you want ....
The picture above is an example of a previewer for an audio file.
Now, before ending this post there two remaining points I would like to address:
1. Current State of the APE: ready for my inhouse projects: the units, besides the pass-through ones, are meant for my inhouse projects, only. Plus, there are some features I would like to add (and even some porting to do) before a public release, if you guys are interested in having this tool, so ...
2. What's next: my idea is to start a fund-raising campaign on IndieGoGo to make a first release of the tool, and some extended goals like developing some units for XNA'ers and Monogamers (so they don't have to), and even doing some porting to other platforms like MacOsX and Linux (since so far the tool only works on Windows for .NET 4.5). And yes, the link at the end of the trailer is not working right now as the campaign is currently on draft mode.
So, this is all for now.
I hope this post sheds some light on what's the APE about and that you guys are interested. It's upto you guys to define whether this baby eventually sees the public light (if not, I'll continue to use it for my inhouse projects). Your call ...
'till next posts!
~Pete
Thursday, December 05, 2013
MY ASSET PIPELINE EDITOR ... FTW!
... behold "The APE" !!
I guess you know the purpose of this beauty, but in case you don't, I'll be posting more details soon.
~Pete
Sunday, March 03, 2013
HOW “OPEN” CONSOLES LIKE THE PS4 OR 720 SHALL BE?
Recently, during the announcement of the Play Station 4, Sony made the promise of bringing the “most open console” for devs.
Discussions have taken place regarding whether by “open” Sony actually means that the new hardware architecture of the PS4 is somewhat more “familiar” than the one chosen for the PS3 console or that the burden to indies will be diminished to some extent.
The phrase is really interesting given that for years the access to dev programs for consoles have been and are still are surrounded by a plethora of red-tape (aka “security”) procedures so that as a rule -as opposed to as an exception, mainly (or if you prefer, only) big companies publish games on their “pro” marketplaces.
To be approved as a professional developer for whatever console, you need to demonstrate that financially you are backed up for the whole development and certification process (upfront fees, updates, deadlines, etc.), you must buy tailored hardware for production to have access to the corresponding SDKs, you need to prove that technically you are up to tough QA checks, and so on so forth.
In recent years, the opening of the XBLIG channel on the XBox 360 console may have seemed for many a change in direction, however, it ended up as a way to bring attention to the console without letting an avalanche of indies stain its reputation and even its status quo to an extent that could threaten the very monolithic model imposed to pros. Never wondered why only a few lucky devs made it into the XBLA channel?
One may argue that by upholding all of the above-mentioned requirements, console enterprises keep low-quality games away from their consoles. To some extent, back in the old days they could have, but today, generalizing the term “low-quality games” with low-budget games or indie games is getting more difficult to sustain (in many cases, such association is unfair).
Ok, but, if this business model has been working fine for console makers, what could make them change to truly support indies?
1. Apple kicked in: like it or not, Apple revolutionized the mobile market for smart phones, smart devices and tablets. But the story did not end there …
On an Industry where sagas were turning out to be far from innovative as well as rather repetitive, Apple was smart enough to truly open the door for indies and their fresh ideas, worldwide.
In fact, and in contrast from what MSFT did with XBLIG, Apple made no difference among devs. Everyone that pays the annual fee has access to the whole pack of features. It doesn’t matter if you are a pro or an indie. Is up to you whether to support any of Apple’s services in your game, develop your own or consume a third-party’s solution.
And every game, regardless its developer, must be tested and approved by a group of Apple’s employees.
All that, the fact that any game (pro or indie) could be picked to be featured on the “AppStore” as well as the growing amount of success stories among indies, contributed to position Apple’s devices on top of the list of target platforms for devs.
2. Google plays: following Apple, Google decided to enter the app-publishing market for Android-based devices, and with NaCl, for browsers.
The amount of devices running Android OS is growing fast and Chrome is strongly incrementing its market-share.
Google’s store, currently named “Google Play” is open for pros and indies, the list of approved countries is increasing, and many games that succeeded in other platforms were ported to Android.
Discussions aside whether you like iOS or Android, there is no doubt that Google Play has served as a model for other big firms, like Amazon and Samsung (with Chillingo), that decided to follow its lead and open a marketplace of their own.
3. The power of the Steam: there are many gamers -particularly hardcore ones- who claim that PC games have nothing to envy from console games. For those gamers, Valve introduced Steam as a means of digital delivery of videogames.
It first started on the Windows platform, then added MacOSX to recently support Linux OS. At the beginning only native-coded bits were allowed, but then Valve allowed managed code.
On recent months, Steam introduced its “Green Light” program, offering new publishing opportunities targeted for indies. In this program, the community decides which games should be granted a green light for publication. One example, is a well-known tower defense game named “Kingdom Rush”.
Steam succeeded where others failed, like Games for Windows, making its services attractive for many devs, globally. The buzz was so loud that now companies like Apple and MSFT have their own stores like the Mac App Store and the Windows Store.
Valve’s next move? The Steam Box console … “Piston” …
4. Secret Wars: imvho consoles as we know them are closer to get obsolete. Why? With current and potential customers buying more and more smart mobile devices over consoles, conditions are changing towards mobility.
As a matter of fact, there is a secret war going on right now among console makers to turn the experience of using a console into a whole multimedia one. Games, movies, music, applications, Internet, and whatever it fits the Cloud-Computing agenda, will be included in consoles.
But it doesn’t stop there … you will be also able to carry that experience with with you on your mobile smart devices. UserId synchronization over the Cloud plays a huge role here. Say that you were playing some game on your console but have to leave, don’t worry, you will be able to continue playing that exact game on your smart phone on the subway without having to start a new match; just resume it and presto! Ditto for movies, music play lists, etc..
Now, you could be asking what indies have to do with this. And the answer is simple, despite their budgets, small companies can react faster to changes in the environment; ymmv, but the larger the payroll and the infrastructure to sustain, the slower a company takes action to accommodate to new conditions on the market, since decisions on a big company usually involves many people on many levels of the organogram.
For each new device, indies would be most likely willing to take a chance. Big companies, unless an exclusivity contract is on the table or at least an exposure/marketing deal, they would wait to see what happens with the device (take the PS Vita for example).
5. Ohhh Yea!: thanks to a surprising campaign on Kickstarter the new upcoming console “Ouya” is about to join the market.
The console will target indies, but this doesn’t mean that you will be able to publish videogames without an approval process.
It’s very soon to foresee the fate of this Android-based console, but if Ouya succeeds, it will put a lot of pressure over traditional console makers, and who knows, all end up being quite positive for indies in the middle run.
So what can traditional console makers do to avoid oblivion?
For starters, traditional console makers must realize that profit is more and more associated to service-based models and less to classic business activities like setting high initial price tags for new consoles.
In this sense, the current monolithic model where dev companies are requested to buy special hardware for production and SDKs, pay high upfront fees, and crazy amounts of money for the QA of updates and patches, could rapidly become a huge stone on the console makers’ shoes.
The more number of games a console gets, the more the makers earn. Plus, they also get a profit from an annual small subscription charged to devs per platform. So the more devs a platform gets, the more profit the platform gets from subscriptions.
The beauty of this equation, is that the console maker always gets a profit from the games you sell and the subscription you pay, even if the game fails on popularity (and you don’t get money out of it). Multiply this income by a large amount of subscriptions and published games and you will have a winning strategy.
Make no mistakes here, this doesn’t mean that games shouldn’t be verified nor authorized before publication, but let the market itself do the ultimate quality-check on published games.
Now, there is an additional key issue to solve in order to assure a critical mass of devs and games. Both, indies and pros should be able to access all official services available for the platform with no distinction. As I mentioned before, on iOS devs can integrate leaderboards, achievements, social interaction, to mention just a few regardless their status as indies or pros.
Last but not least, implementing a proper videogame-exposure built-in system cannot be neglected on each platform. Usually, big companies can run ambitious/aggressive marketing campaigns, so they will likely get a spot on featured areas of the stores. So a way to attract indies is to expose their games as if they were made by pros. The 360’s XBLIG channel is THE example of what NOT to do!
To wrap it up …
The videogame market as a whole has changed big time in recent years. Smart devices introduced new challenges to both, PC and console makers. And thus, to stay in the game one may expect a strategy leap in the middle run on traditional consoles. Or else, these consoles may face an important drop in sells in comparison to previous editions.
How open a console may be deemed will therefore depend on, or if you prefer, will be directly proportional to the less barriers imposed on indies.
Let’s hope that both the PS4 and the XBox 720 consoles get really open to indies this time, by offering an attractive business model, worldwide.
Cheers!
~Pete
Friday, February 15, 2013
THE FATE OF XNA … NOW WHAT?
Lately there has been lots of speculation and comments on the Web regarding the fate of XNA as a result of these blog-posts.
Due to technical difficulties with my main system I am arriving late at the party; many articles and tweets are out now, but anyway, I will give my view on the subject.
For me, the phase-out process that MSFT has been carrying out silently for, what, a couple of years, a year and a half, a year, <include your estimate here>, is not precisely a surprise. In fact, I stopped working in all projects based on XNA tech during late 2010 because something was troubling me.
At that time, I was an XNA/DX MVP creating my game engine, replacing XNA’s Content Manager with my own version of it, developing a videogame, to mention just a few, but for some reason I was holding myself back before starting a game-dev business based on XNA tech.
The hunches -based on facts- that supported my decision back then, in hindsight now prove me right on my wait. Of course it is important to note here that this worked for me; in other words, YMMV.
1. HUNCHES AND WARNING SIGNALS
Let’s see, in no particular order, these are the hunches that caught my attention:
- Comuniqués started to slow down: these were a great read on the XNA Team blog, but suddenly, they started to fade out.
- Our Community Manager moved to another division: we all remember her xxoo’s at the end of her messages and posts. That unexpected departure was the first warning signal to me.
- XNA 4 was gradually presented as a “mature” product: or expressed in a different way, XNA was not likely to receive (major) updates. Maybe this one was very difficult to gather at that time, but for me it was the second warning signal.
- Lack of strong support for XBLIG: how many times community members (and even MVPs) claimed for proper marketing, fast opening of new markets, and or even a decent location on the Dashboard? In practice, MSFT turned out to be reluctant, so third warning signal.
- Lack of XBox Live services for XBLIG: in addition to the previous one, how many times community members claimed for Leaderboards, Achievements, DLC, and so on so forth? Do you guys at MSFT really expect that games with no global leaderboards survive the increasing demands from gamers?
- Communication of Future Moves to MVPs: in the past, before entering a new dev phase, the Team used to involve XNA/DX MVPs on design decisions. Maybe for many readers this is not relevant, but from and MVP’s perspective that to some extent used to be involved in the roadmap, being asked “what do you guys think of …?” a few days before going public, is a warning signal. Fourth one, indeed.
- The format of .xnb files was published to the world: this one might have been handy to me if published a couple of years earlier, but combined with the one below, gives -more than an indication- a confirmation that MSFT was silently phasing out XNA. Fifth warning signal.
- Gradual relocation of all members of the XNA Team: when you saw one one of the most important programmers on the Team go to a different division on MSFT, and no one is relocated or hired to take its place for further development of XNA, (please be honest here) did you really think that everything was ok? Sixth warning signal. A major one, if you ask me.
- Unattended suggestion on Connect: after the database clean-up the XNA Team did on its Connect’s page, suggestions were marked more and more as “Active”, “Postponed”, “By Design” and “Won’t be fixed”. Seventh warning signal.
- DirectX SDK will not be updated any longer as such: let us clarify this point: the DirectX SDK was integrated into the Win8 SDK for the newest version of DX. What happened with the SDK for DX9.0c? Eighth warning signal.
- No XNA 4 for Windows 8 RT: this is a technicality but, given that DirectX 9.0c does not get along with ARM processors, unless XNA gets a redesign based on DX 11.1, it gets pushed out of the picture for Surface (ARM-based) tablets. Since the XNA Team has been erased, unless a new official product comes unexpectedly out of the shadows for .NET, hoping for an official rope is kinda naive. Ninth warning signal.
- XNA does not support WinPhone8, or does it?: after all the worries, talks and efforts to provide safe environments, MSFT does radically change by allowing the execution of custom native code on the new Window Phone 8 devices. This sounded like heaven for XNA’ers until MSFT announced that XNA wouldn't add support for WinPhone8. Games created with XNA for WP7 still run on WP8 devices, but they will not be able to get advantage of unsafe operations for the device. Tenth warning signal.
- XNA is not integrated into VS2012: as a corollary of the point above, XNA was not integrated into VS2012, what in turn means that if you need to use the content pipeline, you will need to install VS2010 side-by-side with VS2012. I don’t know, eleventh?
- No MVP award for XNA/DirectX: I can understand the decision for XNA given that it has been and still is being phased out, but why must the award for DirectX be also doomed? Despite the fact that the SDK is now part of the Win8 SDK, imho it is still a separated kind of expertise that cannot be merged with other areas. Final warning signal = confirmation.
As a former XNA/DX MVP as well as an old timer using MSFT’s technology, let me say that lately it has been really difficult to recommend the use of XNA to create games professionally given the facts above.
What can you say to devs when they ask questions like: “Can I use XNA for Windows RT?”, “Will XNA be integrated into VS2012?” or “Will XNA support DX11?”? Ditto for the question below …
2. WILL THERE BE A NEW OFFICIAL SOLUTION FOR .NET?
It is very difficult to foresee what’s coming next in terms of .NET and game development given the difficulties one may find when trying to deduce what the heck TPTB at MSFT are currently thinking/doing.
But let us see, to update XNA (or replace it) MSFT may consider that …:
- … there is a novelty around “Going Native” with C++11 inside MSFT itself.
- … to support ARM processors, the new tech needs to be built on top of DX11 APIs (which supports “legacy” cards by only enabling the subset of allowed features for the card).
- … XNA is neither a pure DX9-wrapper nor a game engine, making it difficult to justify its maintenance.
- … the dream of “develop once, deploy to the three screens” vanished given that not all the features supported on the PC were supported on the 360 and the WP7 platforms. Plus, the screens are changing: WP8, Surface, XBox.Next, ...
- … last but not least, XBLIG failed as a business line an new lead marketplaces for indies emerge (Win8, WP8). Period.
So, to answer the original question, with C++ regaining position inside MSFT and being DX11.1 mandatory for latest platforms, why bother? Which leads us to the next question …
3. WHAT CAN “XNA’ers” DO NOW?
You feel disappointed. MSFT let you down (for some, again). You cannot find the exit from this nightmare. And you do not want to learn or get back to C++.
If that is your case, then, do not panic! Right now, there are many alternatives out there for you to consider, specially if you like or love C#:
1. SharpDX: created by Alex Mutel -as an alternative to SlimDX, this pure wrapper of DirectX (from DX 9.0c to DX 11.1, both included) has positioned as the lead solution for advanced user who want to program DX games on top of the lowest level available to C#.
Although this set of APIs is open source, it is consumed by many of the solutions that will be listed next. What is more, games for Win8 from MSFT Studios (through partners like Arkadium) have been developed using SharpDX (i.e.: minesweeper, solitaire, and mahjong).
Alex has been also developing a Toolkit to ease development of common tasks (sound familiar?), which for sure extends a bridge to those of us coming from XNA.
2. Monogame: the open source sibling of XNA. Fueled by SharpDX for all latest Windows-based platforms. Multiplatform not only for Windows, thanks to Mono.
With few-to-none modifications to the source code of your XNA creations, you can port your games to a wide variety of platforms.
This open source solution has recently reached its third stable version, adding many requested features, like 3D support.
Although it lacks a content pipeline replacement, which is currently under development, it can be used from VS 2010 and VS 2012.
Many well-known games have been created with Monogame (or adaptations of it) like: Bastion, Armed!, among others.
Last but not least, the community is growing strong around Monogame. As a matter of fact, if you like “the XNA-way” then this is your perfect choice.
3. ANX: a competitor to Monogame. Its name, in case you did not notice, is XNA reversed. Recently, after a long wait, v0.5_beta has been published.
Not many games have been created with this solution yet and its community is rather small –in comparison with Monogame’s, but definitely its progress is worth following closely.
4. Paradox: I really do not know how Alex does to find some time left, but he is also developing a multiplatform game-dev solution for .NET with a data-driven editor!
Of course that the Window-targeted portion of Paradox is based on SharpDX, but the engine will also offer deployment to other platforms based on OpenGL.
No prices or release updates have been disclosed yet, but having read the features, watched images and demo videos, it is by far a very serious alternative to consider.
5. DeltaEngine: the lead dev of this multiplatform solution is the first XNA MVP that wrote a book about XNA.
Coding by using this solution resembles coding with XNA. It has its own multiplatform content pipeline which optimizes output per platform, among other tools. And games like Soulcraft show off the power of the solution.
You can check the pricing here.
6. Axiom: being a former user of this solution before the time of XNA, I am very pleased to see that the project has revived.
Axiom is now a multiplatform solution for .NET based on the popular OGRE graphic engine, which also consumes SharpDX for Windows targets.
Honestly, I do not know whether there are games created (and published) with this solution, but I hope there will eventually be sooner than later.
7. WaveEngine: Vicente Cartas (MVP for XNA/DX) has just let me know about this cross-platform engine, which will be released as a beta in less than a day ahead (thanks for the tip!).
Oriented towards the mobile-dev market, the engine is a result of a two-year effort of the Wave Engine team. Knowing past work of Vicente on JadEngine, I cannot wait to watch some cool demo videos here (like Bye Bye Brain).
Best of all, the engine is completely free, so it is with no doubt worth trying as soon as it gets released!
8. Unity3D: I cannot forget to mention Unity3D since it started almost at the same time that XNA did, however, adoption among devs grew exponentially on later years because of a combo of factors: a robust editor, multiplatform support, increasing number of appealing features, and a variety of well-known success stories among indies (for instance, ShadowGun).
Make no mistake here, the experience of using Unity3D is quite different from XNA’s: its editor-centric, coding -either in C#, Javascript or Boo- serves as scripts, sometimes you need to broadcast messages -as opposed to an OOP rationale, and last but not least, 2D programming is not straightforward (not even on the latest version; you need to buy one of the available plugins as a workaround).
You can check the pricing here.-
As you can see, even if no official solution will replace XNA, its spirit remains in many of its successors, all of which support latest DX11 HW.
So imho as a dev, there is no need to worry. Your knowledge is still valid for the above-mentioned alternatives.
4. OK, BUT WHAT ABOUT MSFT?
Well, imho it would be deemed as positive by XNA’ers (and indies in general) if MSFT …:
- … does not try to impose C++ as the only language to develop quality games.
- … develops a common compiler for C++/C#, for all supported platforms.
- … implements SIMD ops for .NET (please vote for it).
- … reduces differences for .NET among the latest “screens”.
- … publishes as open source the source code of XNA that does not implies a security risk or bring any potential legal issues to the table (like say, the content pipeline).
- … reduces barriers for indies (like say, the access to XBox Live services) for the upcoming XBox.Next so as to compete with other platforms like Ouya, iOS, Steam and so on so forth.
- … and continues to support indies through initiatives like the Dream.Build.Play compo.
Personally, I do not care the language or solution a dev picks to develop a game provided it is the right language or solution for the project. In this sense, this “Going Native” campaign that some people at MSFT may seem to support by stressing perf differences among C++ and C# whenever they can, is imho unnecessary given the fact that there are many successful indie games out there developed with managed code.
Plus, as a former C++ dev, I do not want to get back to C++ because I feel really confortable with C#. If sometime in the future I had to go to a lower level language I would prefer “D”.
Thus, I hope MSFT creates a common compiler for C++/C# which in turn will help us turn the use of hybrid solutions into a common scenario for indies.
5. TO WRAP IT UP …
Without starting a nonsense discussion for a Pyrrhic Victory, imho the fate of XNA was predictable if you took a careful look at announcements from MSFT, whether you deemed them as facts or mere hunches.
But one thing remains strong for sure: XNA’s spirit.
Thanks to solutions like SharpDX and Monogame one can still talk about C# and XNA-based coding as a valid option for a game-dev business.
Cheers #becauseofxna!
~Pete
Thursday, August 23, 2012
INTERVIEWING DEAN DODRILL, CREATOR OF “DUST: AN ELYSIAN TAIL”
What’s the dream of game developers like myself? To get an opportunity, even the slightest one, to publish your own game title on the big leagues. That game that you always dream of creating from scratch. Your masterpiece. Your 9th Symphony …
Some of us, generally “indies”, even dear dream of watching that game become a success once it goes gold. The kind of success that allows us to officially become part of the Industry from that moment and on with a critical mass of loyal gamers waiting for our next tiles with sincere smiles of joy on their faces.
For Dean Dodrill, creator of the acclaimed game entitled “Dust: An Elysian Tail”, the dream has become a reality.
For those of you who still don’t know, Dean’s game (Dust: AET) was the grand-prize winner of the Dream.Build.Play contest held back in 2009. Recently, the game went gold on the Live Arcade marketplace for the XBox 360 console (“XBLA”), as a part of the Summer of Arcade 2012 promotion (“SoA”).
As soon as the game got released, it received (and still does) lots of positive reviews, articles, kind words from buyers, a zizillion of tweets and FB posts, and ratings varying from 8.5 to a perfect-10 score.
Most of them, like this interview with the guys of IGN’s Podcast Unlocked (which I recommend listening to), focus on the story behind the creation of the game and the game itself, from the perspective of gamers.
So, since the game was fully developed with C# and XNA, being a strong supporter of both technologies for years, I decided to try luck and interview him from the perspective of an indie XNA'er.
Well, … guess what? Dean kindly answered all of my questions, so be prepared to read his responses after watching the launch trailer of his game.
Ok, we’re back. Before posting the interview I want to thank Dean publicly for accepting the interview and taking the time to answer all the questions.
Now, enjoy the reading …
Q: Are sells going as you expected? I mean, I don’t want to know the figures; instead, I want to know whether they have reached a point where you can continue developing games professionally (you know, to continue living the dream) or not (= it contributes to make you family’s life better for a while but it is not enough to go beyond).
A: It’s a little early to determine how well sales are going, but I do believe the game will allow me to continue game development, at least at the scale I’m currently working on.
Q: How was it like using the XNA framework –from and artist viewpoint, given your lack of programming experience? (I mean, pros and cons) Which features do you love for C#/XNA to have built-in (I mean, that lacking feature that forced you use a workaround or take a programming detour)?
A: Since I’ve never programmed with anything other than C#/XNA I can’t really compare it to other languages. I will say that I found it fairly easy to pick up, and since much of my code resulted in some sort of visual feedback in the game, iteration was fun. Garbage collection on the 360 was always a hassle, but I loved many XNA specific niceties, such as SpriteBatch and streamlined gamepad support. I also love XACT and how relatively easy it was to work with audio and effects. If I could help I would continue working with XNA exclusively.
Q: Which features of the extended XNA APIs for Live Arcade did you use? Again, how was it like using them?
A: I did have to use the XNA extensions for XBLA, and admittedly most of that was a hassle. The biggest issue is that most of it is poorly documented, and there were always certification issues which were inherent of XNA. Integrating Leaderboards and Achievements was one of my least favorite parts of the process. I definitely got the feeling that XNA wasn’t created with XBLA in mind.
Q: Given that you got a contract with MSFT, do you still own the IP rights of Dust: AET? Did you receive financial advantages, like not having to pay for (re)certification) and or dev/test kits? (if you can comment on it, of course)
A: I do own the IP to Dust:AET, but of course have signed an exclusivity period with MS. MS helped with testing and localization, and assigned me an excellent producer who helped push the game through the system (as well as offered valuable design suggestions). It’s a mutually beneficial agreement, otherwise I can’t go too much into details.
Q: Are you planning additions/extensions to the game? Say, now that you met the deadline for Summer of Arcade, you want to add that feature that stayed behind and would have loved to develop for the release by “unlocking some extra time”?
A: I haven’t given much thought to anything like DLC. Thankfully I didn’t have to cut anything to meet the SoA deadline, it was just a matter of compressing the schedule down and working VERY hard for a few months. Given more time I would have liked to polish a bit more, but that’s the curse of any project I’m sure. I do have plans for future games in this universe, but nothing to announce at this time.
Q: Are you planning to port the game to other MSFT platforms like WinPhone8, Win8 and the Surface? (for instance, by using Monogame or ANX).
A: MS and I haven’t discussed anything outside of XBLA at this time. I was honestly so busy focusing on the XBLA release that I hadn’t considered a port. If anything pops up I’ll be sure to announce it, but XBLA remains my focus as of this writing.
Q: Thanks in advance for reading, your response and for such a great XNA game which serves as a great inspiration for us, indies.
A: Thanks for the interview, Pete.
Game Description:
Immerse yourself in a gorgeous hand-painted world on a search for your true identity. As the mysterious warrior, Dust, your action-packed journey will take you from peaceful glades to snowy mountaintops and beyond. At your disposal is the mythical Blade of Ahrah, capable of turning its wielder it into an unstoppable force of nature, and the blade's diminutive guardian, Fidget.
Battle dozens of enemies at once with an easy-to-learn, difficult-to-master combat system, take on a variety of quests from friendly villagers, discover ancient secrets and powerful upgrades hidden throughout the massive, open world, and uncover the story of an ancient civilization on the brink of extinction as you fight to uncover your own past.
- Take control of Dust, a warrior searching for his true purpose, as he joins forces with the mystical Blade of Ahrah and its guardian, Fidget, to save the world of Falana from an army unlike any before it!
- Explore an incredible hand-painted world!
- Match wits and weapons against challenging monsters!
- Take on side-quests from a cast of colorful, fully-voiced characters!
- Craft dozens of items and discover Falana's rarest treasures!
- Compete against your friends' high scores in ranked Challenge Arenas!
Nice interview, don’t you think?
Not only is the game fantastic but also it may help developers finally understand how powerful C# could be when coupled with a fine tech like XNA, despite unavoidable performance differences with native bits, when you use the tech right even as a one man band (like in Dean’s case).
It’s a pity that many devs (pro and indie) still deem XNA as a tool for kids and hobbyist, only, and don’t give it an opportunity. And what is worse, it’s a shame that MSFT –at least for what is publicly known so far- won’t update it any longer …
To wrap it up, Dust: AET shows off a quite enjoyable gameplay, incredible art as well as the mechanics behind its 2D environment, like skeletal animations, particle systems, input combos, shaders, to mention just a few.
So, what are you waiting for? Go and buy it now!
Cheers!
~Pete
Wednesday, August 22, 2012
DBP 2012: TOP 40 FINALISTS
The list of top-40 finalists for this year’s Dream.Build.Play contest has been published.
Top-20 finalists for the XBox360 console:
https://www.dreambuildplay.com/main/winners.aspx#winnersXbox-tab
Top-20 finalists for the WinPhone device:
https://www.dreambuildplay.com/main/winners.aspx#winnersWinphone-tab
You can read on the page, the following:
The games received for this year’s competition were phenomenal.
It could be, but imvho, compared to previous years, and at least for the 360, there is no game that stands out that much this year visually like The Dishwasher: Dead Samurai, Dust: AET, among others, did in previous compos.
I always wondered why this game was never awarded a prize on DBP 2011. If they had submitted the game again for this year’s compo, they would have run for the 1st place. Its gameplay video looks fantastic:
I hope MSFT eventually gives these guys a chance to get an XBLA-publishing contract even if they didn’t win or make it into the final round.
Having said that, congrats to the finalists of DBP 2012!
Cheers!
~Pete
Tuesday, March 15, 2011
“LONG TIME NO SEE”
For the last few months I have been immersed in a code rush to get my first commercial game published on iTunes’ App Store. And finally, I’m proud to say that it made it into the market!
http://itunes.apple.com/app/just-survive/id424392950
The name says a lot about the game: Just Survive!
I had originally started working on it on 1998 and published it on the web during 1999. At that time there was just one enemy and scores were saved locally. The game didn’t get noticed but many people because everything was much different from the globalization we are experiencing now, but I remember having received an email message from someone who wrote something like:
Nice game. I have been playing it for 45 minutes and I want to know how much longer I have to play it to get to the first boss; btw, highscores aren’t been saved on your server …
That message helped me to decide –a few years after- whether to jump into the indie Industry. And today, here I am …
The game has gone through lots of modifications since then, 90% of them happening during 2010/2011, so I can now say the you’ll get to fight many types of enemies, more than one boss and there’s global leaderboards!
Here’s the trailer on Youtube:
This is one of the four games I have in production for different platforms, so in the following months expect some news about them.
Hope you like it … and buy it!
~Pete
> Link to Spanish version.
Thursday, October 14, 2010
REPLACING THE CONTENT MANAGER API: PRELUDE
As I briefly mentioned in one of my previous posts, for a period of time (close to 2 years, now) I have been developing my own API to manage content as a replacement for the one delivered as part of the XNA Framework.
Why? At first I was trying to circumvent the limitations of the latter related to its inability to properly handle the Dispose operation. And while doing so, I realized -when I checked the source code of the original with “Reflector”- that there was room for improvements (with a redesign).
After almost two years of development as part of my own XNA-based videogame engine (being the latter still in endless development), I decided to redesign my content manager as an independent module so that it can be used with XNA without the need to plug my engine (neither in whole nor in part).
I will not release the source code of my API, so in the next installments in this series of articles I will be discussing publicly what my API has to offer, so that anyone can read it, focusing on The-What rather than on The-How; thus, I will be mainly presenting features and results (I do indeed know, yes, “what a bummer!”).
So, what’s coming next? On part 1 (and most likely part 2 also) I will be introducing my API, explaining differences with the built-in one, and after that I will start to talk about obtained results (yes! With numbers, screenshots and such) for the different platforms I tested.
‘till next time,
~Pete
> Link to Spanish version.
Friday, September 10, 2010
GETTING A REFERENCE TO A METHOD-CALLING OBJECT IN C#
Ok, after taking a month off from any blogging activity, I guess is time to catch up and blog again. And I believe there is no better way of doing so than to write an article explaining a way to get a reference to the object that calls a specific method.
For the last two years or so, I have been working hard on a new Content Manager replacement API for the XNA Framework to use on my own “never-ending” game engine (I will blog about this later on). In some early stages of development I found a way to solve this referencing burden that have been creating headaches to many devs, globally (being me, one of them, for a long time).
Although I must admit that at some point on the development cycle of my API I decided to abandon this workaround, after reading one of the articles mentioned by Shawn here (guess which one), I believe it’s a great opportunity to talk about it.
A little history … before founding this solution I tried everything: from attempting to use –with no luck- the info held in StackFrame instances and even delegates to finally “quit” and use a naive approach as passing the caller as a parameter in the signature of an operation. But, then came .NET Framework 3 and extension methods to the rescue!
Please bear with me that the example presented in this article is just a simple one to show how to use it, but believe my words when I say that it can be extended to complex scenarios.
Having said that … if you want to know which object is calling a certain method of a class like (which may or may not be sealed):
public sealed class MyCalledClass
{
internal bool JustReturnTrue(int myParameter)
{
return true;
}
}
Being the caller, say, a specification of the following class:
public abstract class MyCallingClass
{
public void Print()
{
Console.WriteLine("I am the object which is just about to call
the monitored operation named 'JustReturnTrue' …");
}
}
Then all you have to do is to implement the following generic extension method for the types you want (in my example, “MyCallingClass”):
public static class MyExtensionMethod
{
public static bool ExecuteOperation<T>
(this T mycallingClass, int myParameter)
where T: MyCallingClass
{
mycallingClass.Print(); // Replace it with your own stuff.
return new MyCalledClass().JustReturnTrue(myParameter);
}
}
The trick here is to design and split assemblies and namespaces in a way that all instances of “MyCallingClass” cannot directly execute the “JustReturnTrue” operation (I leave that task as an exercise to the reader).
But there is one catch to watch closely, though. By doing this you are actually adding one more call (you know that), which is not generally a problem on Windows, but for the XBox 360 and all devices using the Compact Framework, it could turn out to be expensive if used lots of times on intensive or heavy tasks/loops.
But if you really need it when speed is not an issue or for operations where -for example- you need to set owners to something “automagically” behind the scenes and later assess whether an owner calls a restricted operation before executing it, then there you have it!
Just use it wisely …
~Pete
> Link to Spanish version.
Tuesday, December 08, 2009
PDC09 VIDEOS AVAILABLE
The videos showing all PDC09’s presentations are now available either for online watch or download.
In particular, for those interested in using DX11 to develop .NET applications & games for Windows 7, check these videos out:
- Developing with the Windows API Code Pack for Microsoft .NET Framework,
- Modern 3D Graphics Using Windows 7 and Direct3D 11 Hardware,
- Advanced Graphics Functionality Using DirectX, and
- DirectX11 DirectCompute.
Enjoy,
~Pete
> Link to Spanish version.
Thursday, September 24, 2009
WATCHING THE SUN BURN - PART 2
On part 1 of the series, I had introduced the lighting and rendering engine named “Sunburn”, from Synapse Gaming.
Well, version 1.2.4 of the engine is out, bringing a boost in performance for the forward rendering technique.
Hereunder you will find my latest results for the reflection/refraction demo (which uses the above-mentioned technique):
1) PC platform:
- Min: 37 fps -> watching the three orbs from almost the roof (close to the windows on top),
- Max: 60 fps -> watching one of the windows on top, and
- Average: 43 fps -> in general (sometimes a bit more on the corridors, not facing the orbs).
2) XBox 360 console:
- Min: 28 fps -> same case as the PC platform,
- Max: 54 fps -> ditto,
- Average: 32 fps -> ditto.
It’s important to notice that, in this demo, the scene is rendered three times per frame: once for the reflect image, once for the refract image, and once for the final output. Why? In order to allow a dynamic behavior. Meaning? Instead of faking the effect with “static” snapshots, what you see is updated and calculated on real-time; thus, moving objects are caught by the process, refracted and reflected.
Again, for both tests I drew the final image on a high resolution back-buffer of 1280x720, but this time I also run the tests on the XBox 360 (both with a varying time step).
Given those results, I cannot wait to see a version with deferred rendering on the XBox 360!
Now, how difficult is to use Sunburn? Let’s just find out, shall we?
I. The Code.
Let’s continue using the “Reflection/Refraction” demo to demonstrate how to use Sunburn. Please download the demo project from SG’s download section before reading on.
When you open the project with Visual Studio 2008, you will find a usual initial structure: the game class and the content folder.
In what follows, I’ll be explaining what’s included in those, based on the example, but only for the code relative to the engine itself:
i. Using Statements
There’s plenty of namespaces to refer, but for this example I will only concentrate my comments on two of them:
1: using SynapseGaming.LightingSystem.Effects.Forward;
2: ...3: using SynapseGaming.LightingSystem.Rendering.Forward;
In case you decide to use Deferred Rendering, you’ll have to change “Forward” for “Deferred” here (and then, as you will notice based on the syntax checking done by VS08, you’ll also have to modify some parts of the code, accordingly).
ii. Fields
The additional fields added to the game class, in comparison to a standard one, can be separated in three categories: a) the lighting system, b) scene members, and c) the technique members.
a) basically, you must declare here both the lighting and rendering managers, plus the helpers that will provide specific data to the system, like environmental information and lighting plus detail preferences.
1: LightingSystemManager lightingSystemManager; 2: RenderManager renderManager; 3: ... 4: SceneState sceneState; 5: SceneEnvironment environment; 6: LightingSystemPreferences preferences; 7: ... 8: DetailPreference renderQuality = DetailPreference.Off;b) along with the meshes that conforms the scenegraph, you must declare all the lights that will be used in the scene plus its respective “rigs”; now, what’s a rig? It’s a container that will store, organize and help sharing the scene lights in the scene.
1: ... 2: LightRig lightRig; 3: PointLight keyLight; 4: PointLight fillLight; 5: DirectionalLight sunLight; 6: ...c) mainly, you must declare the forward-rendering effects along with the render target helpers (the latter give support for reflection, refraction and the usual render-to-texture draw calls).
1: SasEffect orbEffect; 2: SasEffect waterEffect; 3: ... 4: RenderTargetHelper refractionTarget; 5: RenderTargetHelper waterReflectionTarget;iii. Constructor
Moving onto the initialization members, you must instantiate most of the above-mentioned fields and set the lighting and detail preferences based on the target platform.
1: // Load the user preferences (example - not required).
2: preferences = new LightingSystemPreferences();
3: #if !XBOX
4: if (File.Exists(userPreferencesFile))
5: preferences.LoadFromFile(userPreferencesFile);6: else
7: #endif
8: { 9: preferences.EffectDetail = DetailPreference.High; 10: preferences.MaxAnisotropy = 1; 11: preferences.PostProcessingDetail = DetailPreference.High; 12: preferences.ShadowDetail = DetailPreference.Low; 13: preferences.ShadowQuality = 1.0f; 14: preferences.TextureQuality = DetailPreference.High; 15: preferences.TextureSampling = SamplingPreference.Anisotropic; 16: }It is interesting to notice, in case of the PC platform, that the example provides means of selecting the level of detail based on the manufacturer of the gfx card and model number.
1: // Pick the best performance options based on hardware.
2: VideoHardwareHelper hardware = new VideoHardwareHelper();
3: 4: if (hardware.Manufacturer == VideoHardwareHelper.VideoManufacturer.Nvidia)
5: {6: if (hardware.ModelNumber >= 8800 hardware.ModelNumber < 1000)
7: renderQuality = DetailPreference.High;8: else if (hardware.ModelNumber >= 7800)
9: renderQuality = DetailPreference.Medium;10: else if (hardware.ModelNumber >= 6800)
11: renderQuality = DetailPreference.Low; 12: }13: else if (hardware.Manufacturer == VideoHardwareHelper.VideoManufacturer.Ati)
14: {15: if (hardware.ModelNumber >= 3800)
16: renderQuality = DetailPreference.High;17: else if (hardware.ModelNumber >= 3400)
18: renderQuality = DetailPreference.Medium;19: else if (hardware.ModelNumber >= 2600)
20: renderQuality = DetailPreference.Low; 21: } 22: 23: switch (renderQuality)
24: {25: case DetailPreference.High:
26: reflectionRefractionTargetSize = 512; 27: reflectionRefractionTargetMultiSampleType = MultiSampleType.TwoSamples;28: graphics.PreferMultiSampling = true;
29: break;
30: case DetailPreference.Medium:
31: reflectionRefractionTargetSize = 256; 32: reflectionRefractionTargetMultiSampleType = MultiSampleType.TwoSamples;33: graphics.PreferMultiSampling = true;
34: break;
35: case DetailPreference.Low:
36: reflectionRefractionTargetSize = 128; 37: reflectionRefractionTargetMultiSampleType = MultiSampleType.TwoSamples;38: graphics.PreferMultiSampling = false;
39: break;
40: case DetailPreference.Off:
41: reflectionRefractionTargetSize = 128; 42: reflectionRefractionTargetMultiSampleType = MultiSampleType.None;43: graphics.PreferMultiSampling = false;
44: break;
45: }Important: since the engine’s render manager uses by default a “page” size of 2048 pixels for shadow mapping, in case of targeting the Xbox 360, this value must be reduced to 1024 pixels so that the page completely fits within the 360’s EDRAM, thus avoiding predicated tiling.
1: ... 2: renderManager.ShadowManager.PageSize = 1024; 3: ...iv. Loading Content:
First, you must create the render target helpers and apply the preferences, in this case, to render the reflection and refraction effects, to the helper that corresponds.
1: // Create reflection / refraction targets. Note the refraction target is using
2: // the "Standard" type to avoid clipping as the map is used by all refractive
3: // objects (not just one with a specific surface plane). See the comments at the
4: // top of the page for details on why this is done.
5: 6: refractionTarget = new RenderTargetHelper(graphics, RenderTargetHelper.TargetType.Standard,
7: reflectionRefractionTargetSize, reflectionRefractionTargetSize, 1, SurfaceFormat.Color, 8: reflectionRefractionTargetMultiSampleType, 0, RenderTargetUsage.PlatformContents); 9: 10: waterReflectionTarget = new RenderTargetHelper(graphics, RenderTargetHelper.TargetType.Reflection,
11: reflectionRefractionTargetSize, reflectionRefractionTargetSize, 1, SurfaceFormat.Color, 12: reflectionRefractionTargetMultiSampleType, 0, RenderTargetUsage.PlatformContents); 13: 14: 15: // Setup the refraction and reflection preferences. These preferences are
16: // set to a lower quality than the main scene's rendering to increase performance
17: // and because reflection / refraction distortions from the normal map will
18: // hide the quality.
19: 20: refractionPreferences = new LightingSystemPreferences();
21: refractionPreferences.EffectDetail = DetailPreference.Low; 22: refractionPreferences.MaxAnisotropy = 0; 23: refractionPreferences.PostProcessingDetail = DetailPreference.Low; 24: refractionPreferences.ShadowDetail = DetailPreference.Low; 25: refractionPreferences.ShadowQuality = 0.25f; 26: refractionPreferences.TextureSampling = SamplingPreference.Trilinear; 27: 28: refractionTarget.ApplyPreferences(refractionPreferences); 29: waterReflectionTarget.ApplyPreferences(refractionPreferences);Then you must read from disk the values that specify how to set the effects in order to use them as materials.
1: // Load the custom materials / effects used by the additional reflection / refraction
2: // rendering pass. These materials both use the same FX file with different material options.
3: 4: orbEffect = Content.Load<SasEffect>("Effects/Orb");
5: waterEffect = Content.Load<SasEffect>("Effects/Water");
The content of the raw “.mat” files is as follows:
//-----------------------------------------------
// Synapse Gaming - SunBurn Lighting System
// Exported from the SunBurn material editor
//-----------------------------------------------
Locale: en-US
AffectsRenderStates: FalseBlendColor: 0.6 0.6 0.4
BlendColorAmount: 0
BumpAmount: 0.017
BumpTexture: ""DoubleSided: FalseEffectFile: "ReflectionRefraction.fx"Invariant: FalseReflectAmount: 0.5
ReflectTexture: ""RefractTexture: ""ShadowGenerationTechnique: ""Technique: "Technique1"Tint: 0.8627451 0.9254902 0.9647059
Transparency: 0.5
TransparencyMapParameterName: "ReflectTexture"TransparencyMode: None
Next, you load the structure of the Light Rig, which declares each light and its respective settings and traverse the structure to instantiate and set each light.
1: // LightRigs contain many lights and light groups.
2: lightRig = Content.Load<LightRig>("Lights/Lights");
3: 4: // Need to find the lights for later performance adjustments.
5: foreach (ILightGroup group in lightRig.LightGroups)
6: {7: foreach (ILight light in group.Lights)
8: {9: if (light is PointLight)
10: {11: PointLight pointlight = light as PointLight;
12: 13: if (pointlight.Name == "FillLight")
14: fillLight = pointlight;15: else if (pointlight.Name == "KeyLight")
16: keyLight = pointlight; 17: }18: else if (light is DirectionalLight)
19: {20: DirectionalLight dirlight = light as DirectionalLight;
21: 22: if (dirlight.Name == "Sun")
23: sunLight = dirlight; 24: } 25: } 26: }The content of the raw “.rig” files is as follows:
<root>
<LightRig>
<LightGroups>
<GroupList>
<item_0>
<LightGroup>
<Name>EnvLighting</Name>
<ShadowType>SceneLifeSpanObjects</ShadowType>
<Position>
<Vector3>
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
</Position>
<Radius>0</Radius>
<ShadowQuality>0.5</ShadowQuality>
<ShadowPrimaryBias>1</ShadowPrimaryBias>
<ShadowSecondaryBias>0.2</ShadowSecondaryBias>
<ShadowPerSurfaceLOD>True</ShadowPerSurfaceLOD>
<ShadowGroup>False</ShadowGroup>
<Lights>
<LightList>
<item_0>
<AmbientLight>
<Name>Ambient Lighting</Name>
<Enabled>True</Enabled>
<DiffuseColor>
<Vector3>
<X>1</X>
<Y>0.6431373</Y>
<Z>0.04313726</Z>
</Vector3>
</DiffuseColor>
<Intensity>0.3</Intensity>
</AmbientLight>
</item_0>
<item_1>
<DirectionalLight>
<Name>Sun</Name>
<Enabled>True</Enabled>
<DiffuseColor>
<Vector3>
<X>1</X>
<Y>0.972549</Y>
<Z>0.772549</Z>
</Vector3>
</DiffuseColor>
<Intensity>2.6</Intensity>
<ShadowType>AllObjects</ShadowType>
<Direction>
<Vector3>
<X>-0.5012565</X>
<Y>-0.8552828</Y>
<Z>-0.1312759</Z>
</Vector3>
</Direction>
<ShadowQuality>2</ShadowQuality>
<ShadowPrimaryBias>1.3</ShadowPrimaryBias>
<ShadowSecondaryBias>0.01</ShadowSecondaryBias>
<ShadowPerSurfaceLOD>True</ShadowPerSurfaceLOD>
</DirectionalLight>
</item_1>
</LightList>
</Lights>
</LightGroup>
</item_0>
<item_1>
<LightGroup>
<Name>OrbLighting</Name>
<ShadowType>SceneLifeSpanObjects</ShadowType>
<Position>
<Vector3>
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
</Position>
<Radius>0</Radius>
<ShadowQuality>0.5</ShadowQuality>
<ShadowPrimaryBias>1</ShadowPrimaryBias>
<ShadowSecondaryBias>0.2</ShadowSecondaryBias>
<ShadowPerSurfaceLOD>True</ShadowPerSurfaceLOD>
<ShadowGroup>False</ShadowGroup>
<Lights>
<LightList>
<item_0>
<PointLight>
<Name>FillLight</Name>
<Enabled>True</Enabled>
<DiffuseColor>
<Vector3>
<X>0.3803922</X>
<Y>0.8313726</Y>
<Z>0.9411765</Z>
</Vector3>
</DiffuseColor>
<Intensity>3.8</Intensity>
<FillLight>True</FillLight>
<FalloffStrength>0</FalloffStrength>
<ShadowType>AllObjects</ShadowType>
<Position>
<Vector3>
<X>25.83315</X>
<Y>10.99056</Y>
<Z>-75.42744</Z>
</Vector3>
</Position>
<Radius>46</Radius>
<ShadowQuality>0</ShadowQuality>
<ShadowPrimaryBias>1</ShadowPrimaryBias>
<ShadowSecondaryBias>0.2</ShadowSecondaryBias>
<ShadowPerSurfaceLOD>True</ShadowPerSurfaceLOD>
</PointLight>
</item_0>
<item_1>
<PointLight>
<Name>KeyLight</Name>
<Enabled>True</Enabled>
<DiffuseColor>
<Vector3>
<X>0.4627451</X>
<Y>0.8980392</Y>
<Z>1</Z>
</Vector3>
</DiffuseColor>
<Intensity>0.6</Intensity>
<FillLight>False</FillLight>
<FalloffStrength>0</FalloffStrength>
<ShadowType>AllObjects</ShadowType>
<Position>
<Vector3>
<X>25.83315</X>
<Y>10.99056</Y>
<Z>-75.42744</Z>
</Vector3>
</Position>
<Radius>110</Radius>
<ShadowQuality>0.25</ShadowQuality>
<ShadowPrimaryBias>1</ShadowPrimaryBias>
<ShadowSecondaryBias>0.2</ShadowSecondaryBias>
<ShadowPerSurfaceLOD>True</ShadowPerSurfaceLOD>
</PointLight>
</item_1>
</LightList>
</Lights>
</LightGroup>
</item_1>
</GroupList>
</LightGroups>
</LightRig>
</root>
Finally, you load the data that configures the environment.
1: // Load the scene settings.
2: environment = Content.Load<SceneEnvironment>("Environment/Environment");
Being the raw content of the “.env” files the following:
<root>
<SceneEnvironment>
<VisibleDistance>500</VisibleDistance>
<FogEnabled>True</FogEnabled>
<FogColor>
<Vector3>
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
</FogColor>
<FogStartDistance>70</FogStartDistance>
<FogEndDistance>200</FogEndDistance>
<ShadowFadeStartDistance>500</ShadowFadeStartDistance>
<ShadowFadeEndDistance>5000</ShadowFadeEndDistance>
<ShadowCasterDistance>5000</ShadowCasterDistance>
<BloomAmount>2</BloomAmount>
<BloomThreshold>0.7</BloomThreshold>
<ExposureAmount>1</ExposureAmount>
<DynamicRangeTransitionMaxScale>4.5</DynamicRangeTransitionMaxScale>
<DynamicRangeTransitionMinScale>0.5</DynamicRangeTransitionMinScale>
<DynamicRangeTransitionTime>0.5</DynamicRangeTransitionTime>
</SceneEnvironment>
</root>
The remaining tasks are the usual ones with the exception of what relates to the local field of the type “EffectBatchHelper”.
1: ...2: EffectBatchHelper batcher = new EffectBatchHelper();
3: batcher.CollapseEffects(scene); 4: ...What’s its use? It helps to create batches of effects, by analyzing the effects used by each of the models in the scene. Or in other words, it collapses similar “materials” in order to optimize draw calls.
v. Updating:
The only special thing to notice here has to do with the water effect, since on every update call it calculates the normal texture to set to achieve the animation effect on the water’s surface.
1: // Apply the current water animation "frame" to the water effects.
2: for (int p = 0; p < water.MeshParts.Count; p++)
3: { 4: ModelMeshPart part = water.MeshParts[p];5: if (part.Effect is LightingEffect)
6: (part.Effect as LightingEffect).NormalMapTexture = waternormalmapframe;
7: }Other than that, there’s nothing else to comment since all handlers will be automatically updated by the game instance it-self.
vi. Drawing:
As said on the beginning of this article, the game renders the refraction texture, then the reflection one and finally the main output.
I order to achieve this goal, you first must set up the state of the scene.
1: // Setup the scene state.
2: sceneState.BeginFrameRendering(view, projection, gameTime, environment); 3: ...Then, for each “special” map (in this case, in order, the refraction and reflection ones), select the render target, what lights are active and what objects they affect, and draw the scene.
1: //-------------------------------------------
2: // Generate the refraction map.
3: 4: // Adjust the reflection / refraction lighting based on performance.
5: if (renderQuality == DetailPreference.High)
6: {7: keyLight.Enabled = true;
8: keyLight.ShadowType = ShadowType.AllObjects;9: fillLight.Enabled = true;
10: fillLight.ShadowType = ShadowType.AllObjects;11: sunLight.Enabled = true;
12: }13: else
14: {15: keyLight.Enabled = false;
16: keyLight.ShadowType = ShadowType.None;17: fillLight.Enabled = true;
18: fillLight.ShadowType = ShadowType.None;19: sunLight.Enabled = true;
20: } 21: 22: // Add the light rig.
23: renderManager.LightManager.SubmitLightRig(lightRig, ObjectLifeSpan.Frame); 24: 25: // Begin generating the refraction map.
26: refractionTarget.BeginFrameRendering(sceneState); 27: 28: // Clear the depth buffer then render.
29: graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Gray, 1.0f, 0); 30: RenderTarget(refractionTarget); 31: refractionTarget.EndFrameRendering();1: //-------------------------------------------
2: // Generate the water reflection map.
3: 4: // Adjust the reflection / refraction lighting based on performance.
5: if (renderQuality != DetailPreference.High)
6: sunLight.Enabled = false;
7: 8: // Add the light rig.
9: renderManager.LightManager.SubmitLightRig(lightRig, ObjectLifeSpan.Frame); 10: 11: // The water reflection map includes the orbs so add them as dynamic frame objects.
12: foreach (Orb orb in orbs)
13: renderManager.SubmitRenderableObject(orb.model, orb.mesh, orb.currentMeshToObject, sceneWorld, false, ObjectLifeSpan.Frame);
14: 15: // Begin generating the water reflection map.
16: waterReflectionTarget.BeginFrameRendering(sceneState, waterWorldPlane); 17: 18: // Clear the depth buffer then render.
19: graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Gray, 1.0f, 0); 20: RenderTarget(waterReflectionTarget); 21: waterReflectionTarget.EndFrameRendering();Lastly, the scene is rendered for the third time combining both previous maps and thus, getting the final output for the scene.
1: //-------------------------------------------
2: // Render the main scene.
3: 4: // Adjust the lighting based on performance.
5: if (renderQuality == DetailPreference.High renderQuality == DetailPreference.Medium)
6: {7: keyLight.Enabled = true;
8: keyLight.ShadowType = ShadowType.AllObjects;9: fillLight.Enabled = true;
10: fillLight.ShadowType = ShadowType.AllObjects;11: sunLight.Enabled = true;
12: }13: else
14: { 15: keyLight.Enabled = renderQuality != DetailPreference.Off; 16: keyLight.ShadowType = ShadowType.AllObjects;17: fillLight.Enabled = true;
18: fillLight.ShadowType = ShadowType.None;19: sunLight.Enabled = true;
20: } 21: 22: // Add the light rig.
23: renderManager.LightManager.SubmitLightRig(lightRig, ObjectLifeSpan.Frame); 24: 25: // The main rendering pass includes all objects so add the water and orbs as dynamic frame objects.
26: foreach (Orb orb in orbs)
27: renderManager.SubmitRenderableObject(orb.model, orb.mesh, orb.currentMeshToObject, sceneWorld, false, ObjectLifeSpan.Frame);
28: renderManager.SubmitRenderableObject(scene, water, waterMeshToObject, sceneWorld, false, ObjectLifeSpan.Frame);
29: 30: 31: // Apply main scene preferences (higher quality than reflection / refraction).
32: renderManager.ApplyPreferences(preferences); 33: 34: // Begin main frame rendering.
35: editor.BeginFrameRendering(sceneState); 36: renderManager.BeginFrameRendering(sceneState); 37: 38: // Clear the depth buffer then render.
39: graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 1.0f, 0); 40: renderManager.Render(); 41: 42: 43: // Setup and render reflective / refractive pass for water and orbs using additive blending.
44: GraphicsDevice.RenderState.AlphaBlendEnable = true;
45: GraphicsDevice.RenderState.SourceBlend = Blend.One; 46: GraphicsDevice.RenderState.DestinationBlend = Blend.One; 47: 48: foreach (Orb orb in orbs)
49: RenderMesh(orb.mesh, orb.currentMeshToObject * sceneWorld, sceneState, orbEffect, null, refractionTarget.GetTexture());
50: 51: GraphicsDevice.RenderState.CullMode = CullMode.None; 52: 53: RenderMesh(water, waterMeshToObject * sceneWorld, sceneState, waterEffect, 54: waterReflectionTarget.GetTexture(), refractionTarget.GetTexture()); 55: 56: GraphicsDevice.RenderState.AlphaBlendEnable = false;
57: GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; 58: 59: 60: // Done rendering main frame.
61: renderManager.EndFrameRendering(); 62: editor.EndFrameRendering();Each rendering step is started and ended in a similar way than the “SpriteBatch” class does, so there are no surprises here.
Finally, we’re done rendering the scene frame.
1: sceneState.EndFrameRendering(); 2: ...vii. Overall:
All of the provided demo projects, include a detail explanation on what is going on in each example, what greatly help you understand the rationale behind the engine’s processes.
II. The Editor.
Now, you may be wondering: “how can I speed up the modeling process? If I had to manually write material files and so on, I’d be cumbersome!”.
You’re right, but, fortunately the engine comes with a handy editor that spares you from that task.
How? Simple, by using the game class provided by Synapse Gaming, you can change materials, and position lights, among other things.
Note: in order to use the editor you must add one more field to your code: the LightingSystemEditor field.
The following video says it all:
For more videos showing off the Sunburn engine please visit this site:
http://www.youtube.com/user/bobthecbuilder
Well, this is it. Now it’s your turn to do your own tests and share your experience with the Sunburn engine!
> Link to Spanish version.





