Tag Archives: Awesomium

Recent Activities

Been a while since I’ve provided an update, so this will be a big one.

I won the first, and second ever GDSE Game Jams! For the theme “There can only be one”, I created Like Clockwork, a web-based bot programming game where you program your archer to navigate the battlefield, seek out, and destroy your enemies. The second jam had the theme “Time is Broken”, and I made (In &) Out of Time (works noticeably better in Chrome), a web-based adventure game. Both are open source and available on BitBucket here and here.

Asteroid Outpost could be coming along better. I created a nice dialog screen that shows who’s talking, added a new enemy spaceship that’s practically the same as the first, and started to make a new scenario. The new scenario demanded a giant super-structure, but since my game is 2D, I needed to split the new entity into 2 sprites so that it would properly draw over and under other entities in the scene. My entire engine is capable of handling two sprites for a single entity, except the current JSON format I’m using to load entity templates and send entity data to Awesomium. Now I either find a shortcut and move on, or take the time to fix my JSON. Shouldn’t be too bad, but it’s still one more thing I need to do. On the plus side, I was really happy with how quickly I was able to get a new bad guy int he game.

There have been a couple bugs in TeeVee that have been annoying me recently, and I’ve been thinking about completely redoing the UI for a few years, but haven’t made the time. This weekend, however, I finally took the plunge and created a brand new web-UI that replaces the UI portion of TeeVee. The scanning and updating from TheTVDB.com is still handled by TeeVee 1, but I plan to write two stand-alone apps that will do each of those tasks. I must say, TeeVee II is already looking way better. Not only is it significantly faster, but it’s also way sexier.

When I’m done with TeeVee II, I’m not sure if I want to release it open source or what. It’s valuable to the right audience, but my gut is telling me that the audience is too small, and none of my audience will be actively seeking out an XBMC replacement because they don’t know that it could be better. Let me be clear here, it may be better than XBMC for heavy TV viewers like myself. I tried XBMC for a few weeks, and my main annoyances with XBMC were: It’s very folder-based, lack of “favourite” shows, and it didn’t handle sleeping very well. TeeVee is file-based, so you can just download your TV to wherever you want, and TeeVee just picks it up and runs with it. It can save a lot of time if your library is large. You can select favourite shows in TeeVee, and those shows will appear above all of the other shows. I have 157 series in my database. How fun do you think it is to watch Vikings with XBMC? And the last point: if my laptop would go to sleep with XBMC running full-screen on my second “Monitor” (the TV), when I woke up the laptop, XBMC would be full-screen on the primary monitor (the laptop). Anyway, look for TeeVee II hitting the shelves near you!

Awesomium XNA r2 Released

I have updated the Awesomium XNA component to use Awesomium 1.7.1. The most noticeable changes are: improved performance, syntax changes for various tasks, and the lack of smooth fonts over transparent backgrounds.

For performance, my credits screen no longer jerks (at least on my computer), and the performance graph isn’t causing performance issues. Yay!

Creating shared JavaScript objects that persist across pages has changed. Instead of this:

// Awesomium 1.6
awesomium.WebView.CreateObject("xna");
awesomium.WebView.SetObjectCallback("xna", "StartWorld", StartWorld);
awesomium.WebView.SetObjectCallback("xna", "Exit", Exit);

You do this:

// Awesomium 1.7.1
JSObject jsXNA = awesomium.WebView.CreateGlobalJavascriptObject("xna");
jsXNA.Bind("StartWorld", false, StartWorld);
jsXNA.Bind("Exit", false, Exit);

On that note, you’d think that you could create a persistent JavaScript object at any time, with or without the DOM for your page being ready because this JS object isn’t page-specific. But that’s not the case, Awesomium will throw an error if you try to create a persistent JS object before the DOM is ready. I don’t know about you, but I have two modes for my web-GUI to run in: Web Browser mode, and XNA mode. In web browser mode, the most notable change is the background, it is not transparent, I use a still of the background I use in game. In order to automatically detect if I’m in XNA or not, I check for the existence of the global JS object “xna”. But if making the persistent JS object needs the DOM ready, and onDomReady checks for the existence of this object, I have a bit of a catch 22. If I can guarantee that there is a moment between when the DOM is ready and when JavaScript’s onDomReady fires, I can safely create the shared object before anyone notices, but Awesomium doesn’t provide such a method. I tried the event DocumentReady, but it didn’t do the trick. To work around this, I’ve had to register to the DocumentReady event, load a dummy page, when the event triggers, deregister from the event, then create my persistent JS object(s), then finally load the page I actually want.

private void Init()
{
    // Load some dummy page
    awesomium.WebView.DocumentReady += WebView_DocumentReady;
    awesomium.WebView.LoadHTML("<html><head><title>Loading...</title></head><body></body></html>");
}

void WebView_DocumentReady(object sender, UrlEventArgs e)
{
    // Call this only once
    awesomium.WebView.DocumentReady -= WebView_DocumentReady;

    // Create callbacks for Awesomium content to communicate with the game
    JSObject jsXNA = awesomium.WebView.CreateGlobalJavascriptObject("xna");
    jsXNA.Bind("StartWorld", false, StartWorld);
    jsXNA.Bind("Exit", false, Exit);

    awesomium.WebView.Source = (Environment.CurrentDirectory +  @"\..\UI\MainMenu.html").ToUri();
}

Not pretty, but it works. If you know of a better way, leave it in the comments.

Next major change is how pages are loaded. In Awesomium 1.6, you could do this:

WebCore.BaseDirectory = @"..\UI\";
awesomium.WebView.LoadFile("MainMenu.html");

And in 1.7.1 they’re pushing for people to use DataSources, but you can still get by using:

awesomium.WebView.Source = (Environment.CurrentDirectory +  @"\..\UI\MainMenu.html").ToUri();

Last but not least, fonts are rendered opaquely over transparent backgrounds. This ends up making the soft edges of letters render black. Not great. There are ways around this, but I haven’t looked in to them too much.

In-game Component Editor

I have started work on an in-game component editor, doing exactly what I mentioned in my previous post: serializing my components to JSON, sending that through Awesomium to some JavaScript/jQuery/jQueryUI to display controls on the screen. It looks pretty slick. Here’s a short video about it:

As you can see, there’s still some more work required: certain datatypes don’t have an associated control (Vector2 and Color), the numeric sliders’ max-value isn’t fixed (it uses current value * 2), and modifications to the values go nowhere. Once I’m able to live-edit these values, this will become useful for debugging, balancing, and perhaps scenario editing.

Oh, and I may be turning into a Twit. I have started a twitter feed where I will try to regularly post about Asteroid Outpost.

Asteroid Outpost Update 2012-06-12

Over the weekend, I integrated Awesomium into Asteroid Outpost, and it looks pretty sweet, but not only that, it’s easy to make changes to. Instead of posting stale screenshots, how about you check out the screens for yourself! They’re just html after all. Here’s a link to my Awesomium Screens for AO. They will only work properly in Firefox, Chrome, and probably Safari. IE will partially work, but all of the cool CSS3 will be stunted and cause the page to look lame. Also note that the background image in this sample is only 1920×1080, so if your screen is gigantic (like mine), please reduce the size of your browser window for your viewing pleasure. Some things you may not think of trying:

  • Use the arrow keys, and press enter to navigate the menus
  • Press ESC once in the game* to bring up the in-game menu, press again to dismiss
  • None of the text is selectable. This is really annoying for websites, don’t ever do this, but this isn’t a website, and selecting text in a game is weird

If you hadn’t noticed, the multiplayer menu isn’t completely working yet. That will come. I want to get a few more features working first, like tooltips and maybe a console? I kinda want to make an html console, especially after looking at Wolfire’s blog post about doing awesome CSS3 transitions for text entry. Like, is that sexy or what? In case you were wondering, reading Wolfire’s blog is what inspired me to use Awesomium.

Also, MindWorX and I have created an AwesomiumXNA component that you can easily add to your own XNA project. Here’s the project on Bitbucket.

  • not really in the game

Awesomium!

I have recently discovered Awesomium, a “windowless web-browser framework”. But guess what? That’s not all it can do. It can also be used for HTML UIs. Two games that I can name use it right now: EVE Online and Overgrowth (lots of fun btw, but I won’t get into that). In the back of my mind, I’ve always wanted to go back, fix up my UI system, add new features, and correct all the wrongs (of which there are a lot of). UIs are a pain, a massive pain. When you get it right, it’s fun, but I’m so anal that I need to (try to) get every detail right, and make it work as similarly to the Windows controls as possible (at least for the features I implement). Don’t believe me? See this diagram for selection logic in a table that I made several years ago. Mouse scroll wheels and key repeats are some other areas that people get wrong far too often. I should get back to the point before this rant goes on too long.

So yeah, I’m sick of writing UI code and I think it’s time I let go of the reins. Awesomium might be the replacement I’ve been (idly) looking for. In about 30-60 minutes, I downloaded and installed the SDK, looked at some samples, and successfully displayed Google’s homepage inside my XNA window. Pretty straight forward if you ask me. The only tricky part was converting Awesomium’s RenderBuffer to XNA’s Texture2D. I did it like this:

if (webView.IsDirty || webUITexture == null)
{
    webUITexture = new Texture2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, false, SurfaceFormat.Color);
    webView.FlushAlpha = false;
    webView.IsTransparent = true;
    RenderBuffer renderBuffer = webView.Render();
    byte[] imageBytes = new byte[renderBuffer.Rowspan * renderBuffer.Height];
    Marshal.Copy(renderBuffer.Buffer, imageBytes, 0, imageBytes.Length);
    webUITexture.SetData(imageBytes);
}
spriteBatch.Draw(webUITexture, new Vector2(0, 0), Color.White);

Probably not the most efficient way to do it, but it does the trick for now. We’ll see if I have any performance issues when I add this to Asteroid Outpost. Once I got Awesomium drawing, I basically had a working web-browser inside XNA. To my surprise, even YouTube worked, with sound! Pretty sweet. Did I mention that you have to add some bypasses for the mouse? The bypasses for the mouse are easy though. The keyboard? Not so much. In my evening of programming, I didn’t spent enough time on the keyboard to get it working. Here’s what I did get though:

Awesomuim in XNA

Everything except the title bar, and the cornflour blue is being drawn by Awesomium, and if you click the “Link!”, it loads my blog inside the same XNA window (How’d you think I found out it plays Flash?). It’s obviously very powerful. I haven’t played with any interaction between Awesomium and XNA yet, but that’s next on the list, right after I fix the colours. The Blue and Red channels are swapped. I need to play with the SurfaceFormat in my call to Texture2D because Awesomium uses BGRA, while “Color” must use RGBA. I have uploaded the source code for this to Bitbucket if anyone wants to check it out.

Oh, and I added a very quick automatic refresh when the source HTML file has been modified. Finding my CSS errors was a lot easier when I could just look over and see what was going on with every change. Well… it’s basically a web browser, why am I surprised at how easy it is?