Thursday, December 31, 2009

CMake and Git

This week the Intensity Engine has undergone a minor 'reboot': I moved it from SCons to CMake, and from bazaar+Launchpad to git+GitHub. The reasons are as follows.

SCons is a really cool tool, especially for Python lovers like me, but CMake's ability to produce 'native' project files and makefiles is quite important. Basically, on Windows it is easier to make proper builds and installers if you use a Visual C++ project file, as opposed to SCons. I wasn't fully aware of this when I started the Intensity Engine a year and a half ago (being a Linux guy). Also, this will help on OS X, as CMake can produce Xcode project files. So, it made sense to move to CMake.

Moving from bazaar to git was for related reasons. While bazaar works well in my experience, on both Linux and Windows, more than one person has told me it is very problematic for them on OS X. So, since working on OS X is very important to us, and also since in general people seem to prefer git, the switch was done. Basically, I prefer bazaar, but my personal preference isn't enough of a reason to stick with it. Anyhow, after finishing the move, I admit it is nice how fast git is, and GitHub has some nice features as well.

So, the overall goal with these changes is to allow more people to more easily use and contribute to the Intensity Engine. The project is growing, in both lines of code and users, and it makes sense to use the best tools for the most people.

For people currently compiling from source, the COMPILE.txt file explains how to get the source using git and compile it using CMake. If you have any trouble, as usual feel free to ask for help on IRC (#syntensity on FreeNode) or on the forum page.

Thursday, December 24, 2009

Slower Languages for Faster Code

This post is both an update on performance improvements in the engine, and a general comment about how slower languages can lead to faster code, in a somewhat ironic way.

So, the next game (codename 'swarm') has really pushed the Intensity Engine to new limits: the map is huge, both in terms of raw size (4096 cube units on each side, so imagine something like 500x500x500 meters), geometry (the compressed binary octree is 1.1MB), entities (about 1,000 of them), and includes several new gameplay elements (new bot types, new plot triggers and items, etc.).

So, it initially ran very slowly, which was not really surprising. At first glance, this could lead someone to speculate that the engine, with its approach of doing as much as possible in a script language - JavaScript on Google V8 - simply isn't a good idea. After all, Cube 2, the engine we are a mod of, is written entirely in C++ (well, with cubescript in a very, very minor role), and therefore our engine should be much slower than where we started from. So didn't we just make things slower, needlessly?

First of all, that isn't an apples-to-apples comparison, simply because Cube 2 can't run the new gameplay elements that we have. But more importantly to the current topic, if you did mod Cube 2 to run the new gameplay elements, it would almost certainly run this map more slowly. That seems strange at first, but it really isn't. The reason is that, while code-for-code JavaScript is slower than C++ (even with the best JavaScript engines like V8), using JavaScript lets you implement optimizations that don't make sense in C++.

For example, if you have a fixed engine written in C++, you can of course tune it quite a lot, but there are additional things you can do if each map/game/level can customize things through scripts. For example, the swarm map has a lot of mapmodels, and the profiling tool reported that they were in fact a significant factor in slowing down the frame rate. Since the code that renders them is a script, I was able to easily customize it to run faster, by applying some heuristics that work well in this map (like certain ways of deciding when not to render a mapmodel). Those tricks might not work well in other maps, but that is exactly the beauty of a secure scripting language - each map can have its own scripts, downloaded on demand with the map. Also, I customized how physics for collision checks and so forth is done, and various other things.

Basically, you don't want to download a whole new engine for each map. But that is what modding the C++ code would require. With a script language, on the other hand, you can code a lot of optimizations and distribute them with the map, in an easy way. So you end up being able to optimize a lot more.

(There is another factor here, of lesser importance, but also worth mentioning: It is also simply easier to write those optimizations in a script language than C++, because script languages are faster to code with.)

Of course, C++ has its place - the core engine has to be written in C++. Even Java or C# wouldn't be possible, because while being slower by a factor of 2 is fine for 95% of applications, that is not the case with game engines. Half the frame rate is not acceptable! But on top of a 'core' C++ engine, I believe it really makes sense to integrate a script language, as we do, and not just because it lets you run more types of games, but also for performance.

Anyhow, to get back to the swarm game, at this point performance is good: On my not-powerful-at-all machine I get 60fps in the slower areas, dropping perhaps to 50fps with a lot of action. But in most of the map the frame rate is actually much higher. So, the optimization phase is almost over. What is left is to write the scripts for the final boss battle, and then to do a lot of playtesting and tweaking of the gameplay.

Friday, December 18, 2009

Adding Plot Elements

I made a small video to demonstrate how plot elements are added to Syntensity games:



Plot elements are things like doors that need to be opened somehow, or platforms that appear so you can cross otherwise impassable areas. They are typically used in single-player games like Doom. Note that in Syntensity they function in multiplayer mode as well (there is no 'singleplayer mode' or 'multiplayer mode' in Syntensity - all games are always multiplayer-ready. But you can also play them locally with just one player, if you want).

As the video shows, when in edit mode you can see some visualization hints, like effects connecting doors and platforms to the triggers that activate them. The visualization hints show both what is connected to what and in what direction.

There are some other features of plot elements not shown in the video:
  • You can have multiple triggers for a door or a platform, so the player(s) need to trigger them all before it opens.
  • A trigger can also be defined to hold an item. In that case, to open the thing it is connected to, the player must reach the trigger, at which point they get the item, and then they must bring it to the right place.

Wednesday, December 16, 2009

Community Update: Ubuntu Lobby

One of our community members, TheAncientGoat, has been working on a nice Ubuntu-themed map:


Besides looking cool, the map includes some web pages, of the Ubuntu homepage etc. (for which you need to enable the experimental web browser plugin). With the web pages updating live, it can be a nice way to keep up to date on Ubuntu news for people inside Syntensity.

Definitely an interesting project to watch.

Friday, December 4, 2009

Media Plugins

I've been working on media plugins recently, here are short videos of the results:



That is the VLC media player, playing on a surface inside a Syntensity map. Note that sound works, but I didn't record it for this video.



And this video shows embedded web browser windows that you can interact with. The plugin for that might be useful for other projects, so I spun it off as a separate project, Qtonium. The name is inspired by Awesomium and Berkelium, two projects doing similar things.

As to why a new project and not to use Awesomium or Berkelium: Awesomium is apparently going closed-source, or at least that is the only way I can interpret their taking down the code and mentioning 'new licensing terms coming soon'. Berkelium is open source, but it is unclear if it is functional or useful outside of Sirikata, the project in which it is being developed and used.

And in any case, both are based on the approach of taking Chromium and hacking it to work in an embedded manner. In Qtonium I took a very different approach: No C++ at all, and no hacking of a massive and rapidly-changing codebase. Instead, PyQt is used in a straightforward manner, that is, Qtonium is written in Python. It's dependencies are Qt and PyQt.

The only downsides I can see to the Qtonium approach are:
  • Qt WebKit isn't a complete browser, just a 'widget'. For example, when embedding Chromium as a whole, you get plugins (Flash, etc.), caching, various default behaviors (handling page load errors, etc. etc.). That stuff is obviously useful, so this is a clear downside. But the cost (hacking Chromium) is also very high in my opinion. In any case, over time those things can be implemented in Qtonium if people want.
  • Qtonium doesn't share Chromium's separate process security model. This is true at the moment, but it would actually be very simple to adopt, due to Qtonium being written in Python, and Python 2.6's improved support for handing separate processes. In fact if you look at the code, how to do this becomes quite obvious.

Note that this is part of the approach of having all plugins be Python modules. Those modules can of course load C++ code if they need to (like Qtonium loads Qt through PyQt), so this isn't a limitation, but actually the hope is that a lot of things can be done with pure Python (including ctypes). That way, plugins don't need to be compiled, and it's generally very easy to make them work on multiple platforms. C++ plugin systems tend to be much more complex to work with.

Wednesday, November 25, 2009

Per-Client Variables

By default state variables are synchronized between all clients: changes to data are reflected everywhere. This is simple and appropriate for most FPS games. However, some information should only be sent to some clients, like say the inventory in an RPG game. Library 1.3 now allows such state variables, which are called clientPrivate.

A clientPrivate state variable is only sent to the client whose avatar that is. In other words, clientPrivate variables on a player entity are only updated to that player - other clients will not see a value for that variable on that entity. (Note that clientPrivate has no effect on non-player entities.) Of course, the server sees all of the values (and when it updates one, the update is only sent to that player).

Here is an example of how to add such a variable to a logic entity class:
  • secretItem: new StateString({ clientPrivate: true }),

Library 1.3

library/1_2 has been forked into library/1_3. The goal is to keep 1_2 as it is, so all the older games still work, while development moves on to 1_3 (which may include API changes, etc.). So, for new games, 1_3 should be used, especially if you will need new library features, as those will be added to library/1_3.

To migrate a map to 1_3, currently the following is necessary:
  • Remove the map asset dependency on library/1_2 and add one for library/1_3.

  • The map script should include the following line before any other Library.include commands:

    Library.include('library/1_3/');

  • Imports of 1_2 libraries should be changed as follows:

    Library.include('library/1_2/Projectiles');

    should become

    Library.include('library/' + Global.LIBRARY_VERSION + '/Projectiles');

    (this way of doing things will help make future library migrations much easier).

After doing those, the map should work exactly as it did with library/1_2.

Thursday, November 19, 2009

New Game: Racing

A new game is ready, you can get to it from the lobby and play it right now. Here are some screenshots and videos:










As you can see, this is a racing game. We wanted to do something different than the current games (first/third person shooters, etc.), to show the flexibility of the engine, so this is that. Another difference is that this game can be played in both single player or multiplayer, so you can have fun even if people aren't online at the same time (but it's even more fun with them).

Tuesday, November 17, 2009

IRC Plugin + Integration

A server plugin for IRC has been written, and is now used in the main servers - the lobby and the three games it has portals to.

This basically integrates text chat in the game servers with #syntensity on FreeNode, so that:
  • All text messages sent in the game servers are shown on #syntensity
  • Messages sent to the server bots (syntensity0 to syntensity3) in #syntensity will relay the message to people on that game server
This should be useful in several ways. Perhaps mainly in that it lets people on a game server, that have questions, be heard on IRC. So we can give technical support very quickly from there.

The implementation was fairly simple: A plugin in Python that integrates python-irclib. We can probably write similar plugins for other instant messaging systems, if it makes sense.

Thanks to TheAncientGoat for the idea.

Sunday, November 15, 2009

1.1 Release

Revision 1190 is tagged as version 1.1. Binaries for Windows and Ubuntu 9.10 are on the Syntensity Mod DB downloads page. I'll link to them from the main website's download page after a little more testing (if you test them yourself, please say how it went, here, on IRC, or in the forum - thanks!).

The new version has many changes, but most won't be noticeable until maps use the new features. The improvements include:
  • Enable maps to customize move, strafe and jump
  • Support for cutscenes
  • WoW-like mouse movement in Mouselook mode - cursor at borders will rotate the view
  • Allow client and server to (naively) share their home dirs, and do this by default when the server does not specify a home dir explicitly. This makes it much easier to set up a local server.
  • ZeroG module, allowing maps to have zero gravity, custom gravity effects, etc.
  • Vehicles module, to let entities move like simple vehicles (pitch based on floor, thrust for movement, etc.)
  • World.getSurfaceNormal, which allows doing bouncing physics entirely in scripts, + Grenade example
  • WorldSequences module - lets you track players progression through areas
  • WorldSignals module - lets you emit and listen for signals that are relevant to areas in space
  • New Steering module for bot movement control
  • Add absolute x,y to clientClick, allowing maps to have menus
  • Allow scripts on the server to intercept and handle text messages (e.g. can be used as a simple way to let people issue commands to the server, etc.)

Thursday, November 12, 2009

Community Update

Since we launched Syntensity a month and a half ago, we posted on some online forums to let people know about this project, but we have been very low-key about it. The reason is that we are trying to do things gradually: Both with building the technology, and with spreading the word. The idea is to get feedback from people about Syntensity, and then to improve it, after which it makes sense to show it to more people, get even more feedback, and so forth.

This approach is appropriate for us, with our open source development model. It is very different from what people do with closed source development, which is usually to build something behind closed doors for a long time, and then release it in a big public launch, at which point they hope to get a large amount of users as fast as possible.

With that background, I'm happy to report that Syntensity has now reached over 500 registered accounts. So, even though we've been low-key about spreading the word, things are heating up. Another sign of increasing activity can be seen on our forum. This is therefore an appropriate time to make a 'Community Update' post on this blog, to take a look at a few of the neat things people in the Syntensity community have been doing. From time to time I'll make more of these posts.



Psycho v1.0 by Psychosilocybin is an interesting work-in-progress map with an attacker-defender gameplay: Only one team has an object to protect. That team gets points for keeping it safe, the other team gets points for stealing it. Accordingly, the map has an asymmetrical structure, unlike typical CTF maps (that are usually very symmetrical). Here are some screenshots:








Realm Arena is a mod of Map2 by adrix89, which adds some movement capabilities, like double tapping to move in order to 'dash' in that direction ('dash' means to move quickly for a brief time). I think it makes for very interesting gameplay, with much more control of your character.

(Note that currently this requires that you edit your autoexec.cfg, as the map says to do. This will not be necessary with the upcoming release, which makes customizing movement easier.)




(The two things mentioned in this blog post are by no means a complete list - I hope I am not offending anybody by leaving them out. These are just two things that happened to recently impress me.)

Sunday, November 8, 2009

4-Weapon CTF Update

The 4-Weapon CTF game, also known as 'Map 2', has been updated to Map 2.1. When you enter that game from the lobby you will be playing the new version.

The changes are mainly bugfixes and minor improvements, in response to feedback we've been getting. They include:
  • Headshot notifications are now shown to everyone, not just the shooter (so you will know if a headshot was done to you, or to anyone else).
  • The sound for scoring a point now always plays when points are scored (before it was done unreliably).
  • Fixed an annoying bug where fragged characters could, in some cases, change their animation and not look fragged (even though they were).
  • Rockets now do twice as much damage as before (making it possible to frag people with a single direct hit).

More updates and new games are coming soon.

Friday, October 30, 2009

Cutscenes

Cutscenes are now possible:



Cutscenes can be written in scripts, so you can have different ones in each map.

See packages/library/1_2/Cutscenes.js for the code and some examples. This is in /trunk, and will be in the upcoming 1.0.3 release.

Thursday, October 29, 2009

Syntensity Celebrates Ubuntu 9.10

If you read this blog then you probably already know that I am a big fan of open source, and of Linux in particular. I'm also an Ubuntu user, so today the Syntensity lobby world is lighting up with fireworks to celebrate the release of Ubuntu 9.10, Karmic Koala:



Log in to the lobby world to see it in person. (The fireworks effect, btw, like everything else is reusable for your own Syntensity worlds. See packages/base/welcome/KarmicKoala.js in your home directory for example code. Note that that file will only be there after you connect to the lobby world, at which point it will be automatically downloaded.)

I've been using Ubuntu 9.10 for a while now, and it was definitely worth the upgrade for me: It feels significantly faster, and also better supports my hardware. Thank you to the Ubuntu people, and all the open source projects that are included in Ubuntu (the Linux kernel, etc. etc.)!

Btw, speaking of Ubuntu 9.10, the nice people at Playdeb have packaged Syntensity for Ubuntu 9.04 and 9.10, 32- and 64-bit.

Tuesday, October 27, 2009

Easier to Run Your Own Server

Some improvements to server setup have just been committed, which make it much easier to run your own server. The improvements are already available if you are running the latest source code, otherwise, they will be in the 1.0.3 release.

The improvements are:
  • Interactive setup wizard, which you can run by adding --wizard to the commandline when you run the server,

    Linux: ./intensity_client.sh --wizard
    Windows: intensity_client.bat --wizard

    The wizard will ask some questions and create a settings.cfg for you.

  • You can now tell the server what activity to run in a much easier way. Simply paste the URL to the activity (which you can find on the activities page) into the settings.cfg file, specifically into [Activities] force_activity_id. The server will then autodiscover the activity and the map asset IDs for you. (You can still use an actual activity ID, for backwards compatibility.)
For more info, see the wiki page on running a local server.

Saturday, October 24, 2009

New Lobby

(click for a bigger version)


The default world is now the new lobby, shown above. It has portals to other games, and also an interactive tutorial.

You will enter the lobby if you do 'connect to selected...' (and you haven't selected another world), or if you do 'connect to lobby...' in the latest build (1.0.2, available on the download page).

Live changes and improvements to the lobby will be happening fairly frequently.

Thursday, October 22, 2009

1.0.2 Release

Revision 1082 is tagged as version 1.0.2. A new build for Windows and a .deb installer for Ubuntu 9.10 are on the download page.

This is a minor, recommended but non-mandatory update (which means you can continue to use the previous version - the network protocol has not changed, nor anything else that would be a problem for you). It includes the following:
  • 'connect to lobby...' option in the main menu, for directly connecting to a lobby world (which has portals to other ones)
  • Interactive tutorial example code (that is, a map which interactively teaches you the controls)
  • Better debug traces from JavaScript
  • Various improvements and additions to library 1.2 (Roles/Classes, WorldNotices, etc.)
  • Support for CherryPy 3.1+
  • Support for gcc 4.4+
  • A few minor bugfixes

Sunday, October 18, 2009

Portals and the Welcome World


Support for jumping between worlds was added just before version 1.0. To make it useful, I wrote a 'Portal' class which is basically a screenshot of a world, that when you move into (that is, when your avatar walks into the portal), you are sent to that world. In the screenshot above you can see two such portals, which lead to map2 and sketchworld.

This will be used in the 'welcome world', the first world people encounter when they log into Syntensity. The welcome world will be a map with portals to the most important/popular maps, and will also have an interactive tutorial for learning the controls. The tutorial isn't written yet, but you can check out the portals by doing a manual connection to www.syntensity.com:10000 in the Syntensity client.

Wednesday, October 14, 2009

1.0.1

Two weeks after 1.0, we are now releasing 1.0.1, which adds several new features:
  • New example content: A new, bigger map, and new gameplay elements including homing missiles, rockets, a shotgun, headshots with the sniper gun, nicer jumppads, etc. (It was kind of our goal to see how much new stuff we could add in a short time, as a test of the API.)
  • Script API support for displaying HUD text and images
  • Various minor bugfixes and polish
You can see some of this in our new video:



or better yet, try it out yourself. Note that this is an engine update, so you need to download the latest build,

http://www.syntensity.com/toplevel/download/

As always, if you haven't already signed up for Syntensity, you need to do so, which takes just a few seconds. See the links on the main page.

Notes:
  • If you are copying the new version into an existing directory with the old version, you will NOT get the new keybindings (see next note). It is simplest to just unpack the new download into a new directory. (Or, you can delete syntensity/client/config.cfg, which will then be created from scratch the next time the client is run, and you will get the new keybindings and so forth.)
  • Change weapons with 1-4, or cycle by pressing the middle mouse button. H shows a little help.
  • The homing missiles can only be shot if you are locked on a target (another player). The lock remains for a short while after your crosshair is no longer over the target (a notification appears at the top of the HUD).
  • This is an early release, we will probably adjust the weapon strengths, ranges, etc., depending on feedback (we can push those updates between releases). So, let us know what you think needs changing.

P.S. I was very impressed by OpenShot, the open source video editor I used to make the video. Kudos to the OpenShot team for making a very useful program.

Sunday, October 11, 2009

New Weapons

The second game is almost finished, and it will include several new weapons, a new map, as well as various other features, many of them in response to the feedback we received so far.

You can see the current state of the new game if you run the latest from the source code repo (do a manual connect to www.syntensity.com:10002). Otherwise, binary builds will be available soon. Meanwhile here is a screenshot of some rocket fire:

Monday, October 5, 2009

Updates and Updating

We have a new Twitter account that we are starting to use for real-time updates, things like
  • New features notifications as they go live
  • Server status reports
Speaking of new features, I might as well take this opportunity to explain a little about how that works in Syntensity (and of course the Intensity Engine): We are able to add new features between releases, without people needing to download a new version of the client, since
  • The master server is a website, so adding things like the new map creation wizard is possible just like updating any website.
  • Game content is downloaded automatically using our asset system, which will get whatever content you need. And as game logic is written in JavaScript, this includes entire games, not just textures, models, etc. (but also those, of course).
Aside from the map creation wizard already mentioned, we have been working on adding new weapons, weapon recoil, and fixing some bugs with animation speeds and other minor things. Note that the default map you enter is still the original version of the gk1 map, so you won't see these things unless you specifically connect to a server running gk1_a.

Saturday, October 3, 2009

Server Requisitioning Issues / Logs

People are already starting to requisition server instances, and sometimes there are problems, like if an asset or a script isn't set up correctly. That will cause the server instance to shut down, and an error log is uploaded to the master server - but we don't yet have a convenient interface for non-admin users to view it. So we are seeing the error logs arrive, but sadly they don't get to you yet.

We are working on improving this. In the meantime, if you requisition a server and don't see it start up, this might be the reason. You can do the following:
  • Ask an admin for your server logs, on IRC (#syntensity on FreeNode).
  • Run a local server instead of requisitioning a remote one. You will be able to see exactly what output it gives, which should help fix any problems with assets or scripts.
We apologize for this inconvenience. That's the nature of the early stages of an open beta - problems are found, and fixed. Bear with us :)

Edit: This issue has now been mostly resolved. You can view the last server log on your account page (you must be logged in), by clicking on "View last error log from requisitioned server." So, if you requisition a server and it doesn't appear in the list of servers, check the server log there for what caused the problem. A comment about this has also been added beside the 'requisition' button. We are evaluating ways to make this even easier.

Friday, October 2, 2009

Launch: Syntensity Open Beta, Intensity Engine 1.0

Today we are officially launching Syntensity's open beta, as well as releasing version 1.0 of the Intensity Engine. This brings to a close an intensive year of development, but is also just the beginning for this project.

Instructions for getting started with Syntensity can be found on the main page.

Syntensity's open beta launches with one complete game (the gk1 map, which is an insta ctf-type game that also has some automatic gun turrets). But Syntensity is really more of a platform for game creation, not one or two games that we created ourselves. This initial game is just to show what the engine can do, and also to be a basis people can work from (by modding gk1). We'll be making some more example games during the beta (to show more of the engine's capabilities - gk1 covers only a small part of that), but our main focus will be to help people use the engine to create the games they want.

Regarding the Intensity Engine (the open source project that comprises Syntensity's code), it is now at 1.0. It's basically feature-complete for our initial goals, and decently stable - enough for people to start using it, both for Syntensity and other projects. There are some bugs we are aware of, and testing will probably uncover more, but overall things are in fairly good shape. In the near future we will focus on fixing bugs and polish, later on, there are a lot of engine features on our roadmap.

Thursday, October 1, 2009

Automatic Testing: Client and Server

(This will be a mostly technical post.)

There is a lot of work planned for the engine after the launch of the open beta (which is, btw, just about here), so automatic testing is crucial to prevent regressions. Basically, every time you commit a change, you want to be able to run a completely automatic battery of tests that checks you didn't break anything. So far in the Intensity Engine only the master server had automatic tests for it, using Django's test client. Those tests are actually very comprehensive, and have already come in handy. There are also some unit tests for the JavaScript API. But for the client and server as a whole, writing automatic tests isn't as easy: They don't have nice test setups like Django, and what's more, the client is a GUI program, using OpenGL (if it were using a GUI like GTK or Qt, there would actually be some tools to help out).

The tests/ directory contains what I did so far towards this goal, over the last few days. The test setup uses pexpect, a very useful Python module that lets you communicate with processes, sending them input and checking their output. This, combined with the server's Python console, lets the server be tested in a nice fashion: Start the server in a separate process, issue it commands - for example, check such and such state variable of such and such logic entity - and validate the output. Using Python's unittest module, in each test the server environment (home directory, with downloaded assets and so forth) is created from scratch. So all of this together gives an appropriate way to test the server.

The client was a little harder. First off, I added an option to run a Python console, just like on the server (which took some refactoring of the console code). Then, I had to write bindings for 'injecting' user events. That is, by issuing commands through the Python console, the test runner can manipulate the client as if it were an actual person: Move the mouse, click, press a key, and so forth. This took some time to get working correctly, due to how SDL events behave and how the engine processes them. But it appears to now be working as it should.

Currently there are 4 tests. Each of them starts up a master, a server, and a client, runs a map ('storming') and then does one of the following:
  • Modify a state variable on the client and see that it propagates to the server
  • Modify a state variable on the server and see that it propagates to the client
  • Modify a state variable, restart the map, and see that it returned to the original value
  • Modify a state variable, upload the map, and see that the new value is used
In other words, these are high-level functional tests, and they already cover most of the basics: Starting up the client and server, loading a map in each, network synchronization, and map uploading. In particular, they cover basically what someone starting out with the Intensity Engine would do (if they follow README-standalone.txt). So these tests are a good start, while of course many more should be added over time.

The tests take about a minute to run, what with creating an entirely new environment for the master, server and client for each test, and starting them all. (Also, for some reason the injected SDL events are slower than I would expect.) But it's actually kind of funny to watch the tests running, with the mouse jumping around, clicking and keypress sounds, and so forth. (Although I imagine I will get tired of it soon enough, and just go do something else while the tests run...)

Sunday, September 27, 2009

Release Candidate

I'm happy to announce that there is a release candidate :)

The goal is to check that the download binaries work (that is, to check if I didn't forget some DLL, asset file, etc.), and also to check for any major bugs that I missed.

To try the release candidate, do the following:
  1. Download it:

    Windows: http://download.syntensity.com/windows_1.0.zip
    Ubuntu 9.04: http://download.syntensity.com/ubuntu9.04_1.0.tar.gz

    For Ubuntu 9.04 you also need to get some deps, with a simple

    sudo apt-get install libsdl1.2debian libsdl-image1.2 libsdl-mixer1.2 python libboost-python1.35.0 zlib1g

    Note that the Ubuntu 9.04 version probably will NOT work on other Ubuntu versions (except *K*ubuntu 9.04, etc.) or other Linuxes - you would need to compile from source so it links correctly against your distro's libraries. Compiling from source is actually very easy on Linux, see instructions on http://www.syntensity.com/toplevel/intensityengine/ and of course feel free to ask for help (here or on IRC, #intensityengine or #syntensity on FreeNode).

  2. Unpack the download and run intensity_client.bat (Windows) or intensity_client.sh (Linux).

  3. You also need to sign up for a user account, for the release candidate you should do that here:

    http://www.syntensity.com:8888/accounts/releasecandidate/register/

  4. Aside from that, instructions for how to do stuff (log in, join a game, etc.) are on the wiki, in particular you should read

    http://wiki.syntensity.com/introduction

Note that I am announcing the release candidate here, and not on the main website, because I don't want too many people to try it (since there might be a problem with the binaries) - I'm just looking for a small amount of feedback on the release candidate for now. Then if all is well with the release candidate, the release itself can be in a few days. So, until the release, please don't tell anybody about the release candidate, I'd rather their first impression be of the actual release (which will have an announcement on the main website, new video and screenshots, etc. etc.).

Thanks in advance for testing the release candidate!

Tuesday, September 22, 2009

Licensing

In this post I'll clarify some things regarding licensing.

First of all, there are two separate topics here: Licensing for the Intensity Engine and for Syntensity. The Intensity Engine is an open source project, while Syntensity is one particular project built using the Intensity Engine (that happens to be run by the same team).

Regarding the Intensity Engine, it uses the AGPL license. I recently elaborated a little more on the website about this, mainly that game content is not considered a derivative work. That is, if you write a game using the API, the game does not need to be AGPL licensed. It's yours and you can license it however you want. Only if you modify the engine itself, as opposed to creating a game using it, does the AGPL license become an issue. It's pretty much how Blender licensing works - make something with Blender and license it however you want; modify Blender itself, and you need to be GPL licensed.

Regarding Syntensity, my original idea was to require that all content be under a creative commons license or something similar, since I see Syntensity as closely related to the participatory culture movement (but in the context of gaming). By requiring such licensing, all the content on Syntensity would be free for use, in Syntensity and elsewhere. But it turned out that wasn't workable - not everyone is willing to use the same license (some artists insist on -NC licenses, for example). So by picking any one license, it would leave a lot of people out. And by picking several incompatible ones, there would be a lot of confusion. So in the end Syntensity will use the most minimalistic and generic licensing for user-created content: Whatever you create in Syntensity is yours, to do with as you want, but you grant everyone a license to use it freely within Syntensity. So how you let your content be used outside of Syntensity is entirely up to you (and you can completely disallow such use), while inside Syntensity we uphold the idea of everyone working together to create more and better games.

(If granting a license to people to use your content within Syntensity is a problem, then don't upload that content into Syntensity - use the Intensity Engine by yourself to run your content however you want, and with whatever license you want. It's open source, and that's what it's for.)

Intensity Engine 0.9.8

I just tagged version 0.9.8 of the engine, which might end up as our release candidate. Changes include:
  • An apparent fix for the big, worrying bug
  • Smoother camera movement (even in mouselook mode)
  • Flag model (4 colors)
  • Some optional, for-future-use API features (action keys, server teleport)
  • Various tool improvements (texture converter & packager, mass texture replacer, etc.)
  • Various bug fixes

Thursday, September 17, 2009

Intensity Engine API Documentation

A first version of documentation for the scripting API - the API you write games/activities in, also known as "the API" ;) - has been uploaded to docs/. You can see it here. It has a 'hello world' example, a tutorial, and a few big examples of actual working code (a plugin, an activity, etc.) with detailed explanations. This should be enough for people to get started with scripting.

We don't expect to have complete documentation in time for the launch, but with this document and the work-in-progress wiki, we should have enough for now. (The source code itself also has comments, particularly in the important places, and the example games and activities are helpful as well.)

EDIT: We moved to github meanwhile, the latest docs are here: http://github.com/kripken/intensityengine/blob/master/docs/scripting_docs.html

Monday, September 14, 2009

Sketch World Demo

I had some spare time today, so I made a simple 'Sketch World' activity:



You can see the code here. What's nice is that this takes only 165 lines of script, and that includes full multiplayer support (everybody has their own color to draw with, sees everyone else's drawings, etc.).

Sunday, September 13, 2009

Intensity Engine 0.9.7

Another engine version, hopefully the last before the launch. Changes include:
  • Unreliable state variables (useful for rapid updates)
  • History-less state variables (useful for event messages)
  • JSON state variables
  • Upgrade to latest V8 trunk, which allows normal building on 64-bit systems (and should be faster)
  • Automatically comment out irrelevant logging code in scripts (very significant speed improvement, given the extensive logging code)
  • Much faster network protocol for asset info querying, when there are many relevant assets
  • Use .js scripts for models instead of sauer-style cfg files
  • Libraries for game modes (including CTF), guns/firing, health, etc.
  • Autogeneration of tedious parts of V8 bindings code, with new automatic validation tests
  • Script commands to combine images and decompress JPEG 2000 images
  • Various tools, for texture configs, image conversion, release packaging, etc.
  • Various bug fixes
No additional features are intended before the launch, just bug fixes. (The launch is still planned for the end of this month.)

Tuesday, September 1, 2009

Full Circle

Just about a year ago, I started to adapt the Cube 2 (Sauerbraten) engine into the Intensity Engine, a generic gaming/virtual worlds platform - something that can run all sorts of 3D environments, and not just games like insta ctf (which, for any non-gamers reading this, means "instagib capture-the-flag", or "one shot you're dead, capture the other team's flag and bring it back to your base"), etc. This involved a lot of work, among other things removing game-specific code and creating an API that lets scripts take the place of that code. In other words, where Sauerbraten has C++ code for insta ctf, the Intensity Engine has only an API, that lets JavaScript code implement all sorts of 3D 'activities', just one of which might be insta ctf (and others of which might not even be games).

Syntensity, however, is focused on games (at least for the near future), and it will launch with insta ctf as its main gameplay mode. So, over the last 4 days I wrote an insta ctf 'activity' for the Intensity Engine entirely from scratch. This ended up taking about 650 lines of code, split up into several components:
  • GameManager: Keeps score, assigns players to teams, and in general manages the game. Plugins for the GameManager let you control things like what determines when the game is over (a high enough score, for example).
  • Health: A plugin for the player class that adds a 'health' attribute ('state variable' in Intensity Engine terminology) to players, and manages player death and respawning.
  • Firing: Handles guns and their behavior (including delays after firing, etc.). A SniperRifle example gun gives the 'insta' gameplay element - one shot and you're dead.
  • CTF: A plugin for the GameManager that handles the flags and their behavior.
By using a component model, the code ends up being very extensible: The 'insta' element is entirely contained in the SniperRifle class, and the 'ctf' element in the CTF plugin. These could easily be swapped out with other plugins to get new gameplay modes.

(All the code is already in the repo, if anyone wants to take a look.)

So, after eliminating all the hardcoded insta ctf stuff in Sauerbraten, we have come full circle to implementing an insta ctf game mode, but this time written in JavaScript, and it's just one example of an activity which the Intensity Engine can run. Amusingly, insta ctf in Sauerbraten and in the Intensity Engine look quite similar from the outside (well, they would if we used the same models), but the internals are entirely different.

Tuesday, August 25, 2009

Intensity Engine 0.9.6

I had hoped to release version 1.0 of the Intensity Engine before the end of the summer, but the final remaining task - some nice example maps - hasn't worked out yet. There seem to be two main problems:
  • It's hard to get maps with commercial-friendly licenses (like CC-BY-SA), which is a requirement for inclusion in the Intensity Engine. There are two main issues here: That some mappers don't want to release their work under such a license, and that many or all existing maps use textures and models that have limiting licensing.
  • A typical chicken-and-egg problem: Release a stable 1.0, and people might start mapping with it, but to release a stable 1.0 we need some maps.
So, the 1.0 release of the Intensity Engine is still pending. However, that won't delay the launch of Syntensity, which should be in a month or so - preparations for that are going well (and it doesn't have the two problems mentioned above).

So instead of releasing version 1.0, I have meanwhile partially lifted the feature freeze on the Intensity Engine, and the current version is now 0.9.6. Changes include:
  • New master server, written from scratch using Django and CherryPy. The old minimaster and asset servers are deprecated (asset storage is now a component in the master server)
  • JPEG 2000 support, for significantly smaller downloads (at the cost of decompression delays after downloading)
  • Copy-paste of entities when mapping
  • Component and signal system for the client and server
  • Plugin system for the JavaScript API, and several example plugins (projectiles, etc.)
  • Allow custom animations (up to 128) per model
  • Enable the Cube 2 ragdoll system
  • Config file autogenerator and converter (from Cube 2 configs)
  • Improved textures for water, lava, etc.
  • Various bug fixes

Monday, August 10, 2009

Introducing Gregor

I'm very happy to announce that Gregor Koch has joined the Syntensity team. In the past he has worked at many game companies, including Crytek where he worked on the CryENGINE. You can see some of his recent work running on the Intensity Engine in the video below.

With Gregor in charge of art and design, we should have some very impressive game content for the Syntensity launch.

Friday, July 31, 2009

Development Update

1. What is hopefully the last memory leak has been fixed in revision 484, after a few days of investigation (turns out it involved how NPC position updates were sent from the server). At this point there are no significant remaining bugs that I am aware of, code-wise things are basically ready for the 1.0 release of the Intensity Engine.

2. After 10 days of fairly strict test-driven development (the Django test client is quite useful), the new master server is mostly complete. It should soon be usable as a replacement for the minimaster.

Friday, July 24, 2009

New Master Server in Progress

I'm writing a new master server which will replace both the Syntensity master server (which was hacked together a long time ago, as a proof of concept, and never open sourced) and the minimaster (which will remain useful for testing, standalone demos, etc.).

The new master is in /master_django. It's written, as the name indicates, using Django, and includes a script to run it on CherryPy, which makes deployment very easy (the Django dev server isn't suitable for production, which is why something like CherryPy is needed; of course, you can also use Apache/lighttpd/etc., but that requires some setting up).

The goals with the new master server are
  • Clean extensible codebase: Beyond the basic functionality, additional features will be implemented as plugins
  • Federation: Allow anyone to easily customize and run their own Intensity Engine master server
Note that the new master is orthogonal to the Intensity Engine 1.0 release - it's optional at this point, and the 1.0 release won't wait for it. What does depend on the new master is the public launch of Syntensity. In other words, the current status is:
  • The Intensity Engine 1.0 release depends on the existence of a few good maps/games
  • The public launch of Syntensity depends on the Intensity Engine 1.0 release and on completion of the new master server

Friday, July 17, 2009

Platforms Video



I've been mostly busy with the business side of this project in past weeks, but today I found the time to do some coding, so I worked on another optional library, Platforms.js, a platforms library for multiplayer. This is still kind of buggy, but the basics sort of work.

Saturday, June 27, 2009

Autoturrets Video



This is done using the Projectiles.js library, which is now mature enough to be put in the standard library. Note that like all other libraries, it's entirely optional, and work on it cannot affect the stability of the engine or the core API (which is why it was added during feature freeze).

Some details:
  • The automatic turrets are controlled by the server, with projectiles managed on both server and clients for responsiveness
  • The turret model was kindly contributed by Gregor Koch under a creative commons license, and consists of a base that turns left and right and a barrel that turns up and down (the commands to render the separate parts are done by a script). Edit: For a closeup, see here.
  • Notice the reflections of the shots in the water
  • Music: The intro to "You Can Take The World" by Predator, from their album Sick Society

Thursday, June 18, 2009

Intensity Engine 0.9.5 Release


More screenshots can be seen here.

Since 0.9, a month and a half ago, a lot of work has gone into the 0.9.5 release which is out today (rev. 324). This release is still not considered stable, but is a significant step towards that (in fact it may be the last release before 1.0). Two main areas of focus in this release are:
  • Allowing people to run their own infrastructure - master server, asset servers, and server instances - without any connection to Syntensity. This allows both federation (separate independent servers, with loose connections - like the WWW) and makes it easier to customize the Intensity Engine for non-standard uses.
  • Improving content creation and collaboration. This is now in a good enough state to allow focusing on content creation, which is one of the main tasks remaining before the Intensity Engine 1.0 release and public launch of Syntensity.
In more detail, here are some of the changes:
  • 'clientSet' state variables, which are applied first on the client, allowing better responsiveness in an easy way
  • Initial login to server instances made faster
  • AreaTriggers made significantly faster, and now work correctly on server
  • Allow maps to extend the position protocol messages, for faster updates of map-relevant information like custom animation settings
  • Allow rendering models (including players) from map scripts, for more flexibility in visuals
  • Added almost-finished Stromar character model
  • Update of server-side NPC/bot system to current API
  • Various API extensions (e.g., allowing gravity to be changed)
  • Various minor GUI and usability improvements
  • Full support for building on Ubuntu 8.10, Ubuntu 9.04, Windows XP and Windows Vista
  • Plenty of bug fixes
Binary builds aren't planned for this release, as things are still moving quite fast.


Towards 1.0

The Intensity Engine is now in feature freeze. Only bugs in existing features will be fixed for the 1.0 release, which is dependent upon
  • a decent level of stability and polish, and
  • a reasonable amount of working content that can be distributed with the engine or at least used to demo it

Thursday, June 11, 2009

Roadmap Changes

I've made some decisions regarding the roadmap for the next few months:
  • The Intensity Engine has been made completely independent of Syntensity, and will continue that way. My original intention was that I would focus on Syntensity, and through that promote the Intensity Engine (the Intensity Engine being an open source project utilized by Syntensity), and later on get around to making the Intensity Engine more compelling as a separate project. But several people (for various reasons) have already expressed an interest in the Intensity Engine by itself, and I have also been hearing some very good arguments for completely open sourcing the Syntensity master server. Because of that, I've started to add to the Intensity Engine the functionality it needs to be usable without the Syntensity master server, namely, an example master server was committed a few days ago, and better documentation on running the various server components as well. Furthermore, improved master and asset servers should be appearing soon.
  • The Intensity Engine 1.0 release is still planned for later this summer. Bugfixing is progressing well, and no major features are planned at this point, just minor stuff. Recent decisions like including a master server as mentioned above should not be a cause of delay.
  • Syntensity will remain in 'closed' alpha, and later 'closed' beta. I say 'closed' with scare quotes, because the source code is open, and I'll give an invite to Syntensity to anyone that asks, so 'closed' here is kind of a silly term. But what I mean is that I won't make an effort to promote Syntensity, and probably not provide pre-built binaries either. The reason is that I think opening up to a wider audience should wait for better content, and it looks like getting that content will take less time than I originally thought, so why not wait.
  • The Syntensity public launch might be delayed somewhat. Basically I will delay it until I feel the content is good enough, probably not by very much, but there is no reason to have a rushed release.

Friday, June 5, 2009

Code Quality Improvements

The Intensity Engine's stability has significantly improved over the past two weeks. In fact, it's been a few days since I ran into a bug. But, the bugs you don't know about are just as bad, so I spent a few days doing various code quality procedures, including running valgrind and doing more serious cross-platform testing.

Valgrind is an excellent Linux-only tool for detecting memory errors at runtime (and a lot of other stuff). For memory errors, valgrind basically checks every memory allocation, read and write to see that it's valid. This is quite an intensive process, making the program run 10 times slower or worse, but one of the nice things with Cube 2 is that it's so fast that, actually, you can run it in valgrind at a decent speed and perform actual tests. And I'm talking about the client, not the server (which can also be done, but is a much less impressive feat).

Even so, running valgrind is a time-consuming task, as it takes a lot of repeat runs to get useful results (as you fine tune the 'suppressions file', the list of warnings that it can safely ignore). This took a few days, during which the following came to light:
  • Several minor issues with Cube 2 itself, including accessing uninitialized values and a mismatched new/delete. I reported them and eihrul committed appropriate fixes (which I then ported to the Intensity Engine). I am somewhat surprised none of these led to noticeable issues in practice, but I guess most compilers initialize enough stuff by default to prevent it. (Perhaps compilers should have an option to not initialize values, for testing purposes?)
  • One serious issue with Cube 2, concerning bone processing in the skeletal animation system: When bones were 'unused' (not appearing in actual blend weights, etc.), that led to a read at index -1 in a C array. As with the previous issues, I reported this and eihrul committed a one-line fix.
  • One minor issue with how the Intensity Engine uses Cube 2: I assumed a value was initialized by default, but it wasn't (not sure why it isn't, it somewhat goes against the conventions elsewhere, but regardless the fix was trivial).
  • One serious issue with, of all things, the Intensity Engine's logging system: An incorrect reuse of a function receiving a variable number of arguments by functions passing it only one (it got confused in some cases and looked for arguments that didn't exist). The fix was trivial.
This actually went better than I expected: Given the 65,000 lines of Cube 2 code, some of which I modified, +30,000 lines of Intensity Engine code that I wrote, I would have expected more issues, or at least more serious ones. Only one serious issue in each of Cube 2 and the Intensity Engine is not that bad.

As a side issue, the trickiest part with running valgrind turned out to be Google V8. Valgrind reports a lot of issues in V8, presumably because V8 dynamically generates machine code from JavaScript, and furthermore modifies that machine code on the fly. In other words, the issues valgrind finds aren't problems with V8 itself, but with the dynamically generated code. And generating an appropriate suppressions file for such stuff isn't easy (not sure it's even 100% possible).

The second thing I did was finally get around to some serious testing on Windows, as during the last few months I only found time for some partial testing myself now and then, and some very useful community contributions. So, the time was right to make sure this worked, and after several hours the client was running fine (there remains an issue with the server, something minor about how linking is done, which I'll fix later on). Interestingly, as always cross-platform testing uncovered some stuff:
  • The serious issue mentioned above with the Intensity Engine logging system led to actual crashes on Windows (while on Linux no errors occurred in practice). So, interestingly, this problem could have been discovered by either valgrind or by cross-platform testing.
  • An issue with reading files using the C API: What I wrote worked fine on Linux, but not on Windows, apparently due to underlying platform differences. The fix was trivial, and even shortened and improved the code: To use Python's file reading system, which is already tested for cross-platform compatibility.

Overall, writing in C++ definitely has its downsides, as the issues mentioned above will attest, and that's why big parts of the Intensity Engine are written in Python or JavaScript: No memory leaks (for the most part), no invalid memory accesses, fewer cross-platform compatibility issues, etc. But with game engines and virtual worlds platforms, the core speed/memory-intensive part really has no choice but to be written in C++. It's not easy nor always fun, but it is manageable.

Monday, May 18, 2009

Friday, May 15, 2009

Preliminary Screenshot

Here is a screenshot from the work-in-progress example game (click on for a larger version):


This is the view from the stairway into the fortress, with the main tower to the right. The character model is just a placeholder (it's from the Yo Frankie! game), the actual model isn't yet finished.

The game itself is starting to be functional: There are teleporters, a cannon that fires characters up into the fortress, and a complex particle effect shown when the top of the tower is occupied. (All of this is done in JavaScript, in quite readable code - which is really the whole point of the entire platform.) What remains to be done is weapon fire and some polishing of the map, and for the final character model to arrive, at which time the alpha will be officially launched. The game won't be fully complete at that time, but that's part of the purpose of the alpha - to playtest it with more people, and to create other games as well.

(Edit: Removed second screenshot; a nicer version of it will appear in the next blog post.)

Friday, May 8, 2009

Alpha Launch Almost Ready

Some near-final preparations for alpha testing:
  • After several months behind closed doors, the latest source code has been uploaded to Launchpad. See important notes below.
  • Bugfixing is progressing well, with little left to do before the launch.
  • The first player model is also progressing well. Screenshots of that should appear here soon.
  • A demo map is in the works. Screenshots of that should also appear here soon.
  • A new logo is being designed (this time by a professional, as opposed to me).
  • The main website has been updated and now contains a page about the Intensity Engine, which includes some new info on technical features as well as licensing.

Regarding the abovementioned 'new info', the main points are
  • Google V8 is now used for game logic scripting, both client- and server-side. In comparison to the previous Python-based system, this provides much better performance and security, and also has the benefit of JavaScript being familiar to an extremely wide audience. I'll write an in-depth blog post about this soon.
  • A brand new asset management system has been developed. It's written in Python, supports nice features like dependencies, zipped assets, and mutability, and should make life much easier in general, both for those creating content and those interacting with it.
  • The Intensity Engine's license is (as before) the AGPL, but with some important qualifications (primarily accepting Apache 2.0 code and not requiring copyright assignment - see the Intensity Engine page for details). We're trying out a new approach to licensing here (or at least I'm not aware of any project doing this sort of thing), and it'll be interesting to see how it goes.

Important notes about the code:
  • This is alpha-stage code, so crashes etc. are to be expected - use at your own risk.
  • There are no binary downloads yet, only the raw code. We'll build binaries and provide them when we launch alpha testing, but even then, rapid changes might make it impractical. So steady releases of binaries might wait for beta testing.
  • If you do compile the code, note that both the client and the server require interaction with the master server (www.syntensity.com). Without an account on the master server you won't be able to do much. Contact us (contact -at- syntensity.com, or on IRC, #intensityengine on FreeNode) if you want an account, and we'll set you up.
  • The current version number is 0.9, reflecting the fact that almost all of the features intended for 1.0 have been completed. The 1.0 release is expected to occur during the summer. Minor API changes are expected until then, but nothing major.

Wednesday, April 22, 2009

Intro

Hello, this is where I'll blog about Syntensity, an open source gaming/virtual worlds platform. The name is a shortening of "Synthesizing Intensity" - by which I mean the creation of captivating, immersive gaming experiences.

Syntensity is a continuation of the Intensity Engine, which (briefly) is a client+server for 3D games/virtual worlds (which utilizes Cube 2, SDL, Python, and various other open source libraries/projects). "Intensity Engine" will continue to be the name of the code for the core client+server package, whereas Syntensity is the combination of the Intensity Engine with a central website and active support infrastructure (stuff like user management, collaboration services, asset hosting, etc.).

The Intensity Engine will remain open source, as always intended. Anyone can take the code and do whatever they want with it. Syntensity is in addition a complete service, based around the Intensity Engine. It's a single 'world' (or 'universe'), you might say, that you can log into and do stuff in.

Syntensity's main focus is on collaborative creation of games - in a way that hasn't really been tried yet. The goal is for participants to 'build' the world themselves, writing new games and improving upon existing ones. (How this is done will become clear later on, when the platform goes live.) Thus, Syntensity's slogan is 'Participatory Gaming' - in reference to participatory culture.

Syntensity will be free. This is possible because every part of the server infrastructure - from individual game servers (called 'server instances' or 'instances' in Syntensity) to the asset metadata backbone - has been built for efficiency, keeping costs low. So, I am funding the initial expenditures myself. In the longer term, depending on how fast Syntensity's userbase grows, obviously some source of income will be necessary. And, I believe there are a lot of interesting business opportunities around Syntensity, which don't contradict (1) the code being open source and (2) normal usage of the service being free. I am thinking about stuff like advertisements, premium services, and so forth.

Note that 'games' have been mentioned quite a bit in this post, and 'virtual worlds' a lot less. The reason that I'm focusing on games is that - at least to get started - it helps to have focus. But nothing in the technology prevents more general virtual world uses.

So, where does all of this stand? The immediate reason for my writing this post is that, yesterday, I ran the first successful integrated test of all the components: I set up a game, logged into it, moved around and edited, and successfully saved my changes to the central infrastructure. Doesn't sound like much, but it involves all of the components working together, many of which are either completely new or have seen extensive changes in recent months.

So, the code for the initial release is basically written at this point. I hope to soon start alpha testing, on an invitation-only basis in order to keep things manageable (but, the code to the Intensity Engine will be open, so anyone else can play around with it if they want). This will happen as soon as

  • I get the code a little more stable, and

  • when the artwork is finished (I hope to receive it soon, so far it's looking very good)


and assuming there is no sudden development on the business side that warrants changing the timetable. So, most likely in a few weeks.

I purposefully haven't linked to anything, as there really isn't much to see yet. I'm also not promoting the project either, except from writing this post. For now, I leave you with the following kind-of-meaningless screenshot of the client GUI (but better than nothing...):


Actual screenshots as well as videos should appear here soon.