Unspoken 0.11
I've put a new release of unspoken up. This one fixes the inability of Unspoken to play sounds when the review cursor isn't following the system carrot or the system focus. It is here.
Let me know if it has bugs.
I've put a new release of unspoken up. This one fixes the inability of Unspoken to play sounds when the review cursor isn't following the system carrot or the system focus. It is here.
Let me know if it has bugs.
OpenAL is great. The proceeding sentence is sarcasm. This post talks about why openAL is not in fact great, and why you don't actually want to touch it without good reason. The motivation for this is the following: as part of the new Camlorn_audio, in order to obtain features that are pretty much considered standard these days, I am preparing to generate 100+ C++ classes with a script, the equivalent in C helper functions, or the equivalent in C helper macros. I am basically writing Twisted, the C++ version;there is a concept of deferred execution. Everything must be on a background thread. Everything is very unhappy. This unhappiness is OpenAL.
Clang_helper, here, is now useful and is also extracting everything available in the OpenAL headers except for comments. It's still a bit rough around the edges, but is definitely workable, especially once I write a better abstraction around C types. Currently, they are strings, all be it standardized-ish ones.
C++ support is unfortunately nontrivial, and probably won't be happening soon. I believe, however, that I can get it understanding and describing C structs. The problem withC++ support is that it is incredibly hard to abstract things without losing meaningful information. As the primary purposes of this project are automatic code generation for languages supporting C FFI and automatic code generation of C functions into C++ classes, this is not a current goal.
The Camlorn_audio approach is going to be a bit unusual: wrap C++ classes into C functions automatically without human intervension, store information on them, and then spit out bindings-at all points in this process, the Camlorn_audio build system will have information on the functions it's generating for itself, and won't need to read the class. Basically, there will be some templates and some yml files, and code will come out the other end. Classes will be declared in yml instead of C++-this gives me sanity, for the moment.
That said, expect me to backtrack on this in a few months and actually implement C++ support into clang_helper. It would be cool if it could, but I am currently at a loss as to how to not lose necessary information. C++ is incredibly complex, and automated C++->C generation in the general case is a hard problem.
Simple things like vector<int>
start to illustrate this-what about vector<vector<int>>
? How about vector<string>
? Each of these quickly becomes a special marshalling case as to how to convert the data. It probably requires some sort of dynamic pipeline that can reconfigure itself, at the least.
The only way it can be easily done is to limit oneself to some subset-C++ classes that make use of only pointers and C types shouldn't be so bad, and basically staying away from templates is required. Good luck on finding libraries meeting them in the wild, though.
Things you can't touch include, well, the Stl. There go half the nice things in the language.
If my current rate of programming skill increase continues, I may be able to handle this in the near future. They say that the worst programmer you know is yourself from 10 years ago; the worst programmer I know is myself from 6 months ago.
Also, the point of not using swig for Camlorn_audio which already handles that difficulty: being able to do things Swig can't, by storing meaningful information (for example, throwing exceptions in languages that support it and being able to not need precompiled C extensions for some things). The meaningful information is not included with C++.
I stand at the point of being able to begin on the Camlorn_audio rewrite, and believe that it will go much faster than the first time. It will probably also be an order of magnitude smaller: the scripts to generate things should be on the order of a few hundred lines, not a few thousand. It will still depend on Boost for the time being, as well as Libsndfile (removing the Libsndfile dependency is a goal; there's no good way around Boost until everyone has C++ 11 capable compilers). I will probably not use SCons. I might write my own small build system, as I've probably got a fairly major nonstandard build step.
In regards to the MMO: I'm trying to get this done first, as the MMO keeps running up against "X needs to be a feature in Camlorn_audio". Most notably, callbacks. I'll discuss my plans for dealing with callbacks another time once I finish figuring them out.
Quick update on Camlorn_audio: it's being rewritten.
here's why:
The current code works, but features are missing. This is because everything must be hand-typed, changes must be made across the entire codebase, and the OpenAL spec must be frequently consulted.
The current code works, but has bugs. Most of these are related to openAL error handling, and a few to threads.
Features that need to be implemented can't be implemented without rewriting streaming, which is the only nontrivial code in the entire thing.
In about 3 hours this morning, I succeeded in writing a 50-line script that turns all OpenAL macros into JSON. In about 6 hours this weekend, or when I get the time, I can probably follow it with a hundred-line script that does the same for all OpenAL functions.
A few things fall directly and indirectly out of such metadata:
All low-level classes for anything, now and possibly in future, can be trivially generated. This is easily 4 or 5 hundred lines.
All low-level classes can trivially have their functionality changed, i.e. error checking improvements, better threading, caching/recording for cloning, serialization...etc...
The bindings for Python can be auto-generated. So too can the bindings for your favorite language, whatever that may be.
Properties can be set by name, i.e. from a string.
You can query the metadata directly, getting lists of OpenAL properties and their ranges/possible values.
By folding the documentation into the metadata (human-generated, unfortunately), documentation can be released in the native format of the binding's language. Furthermore, for languages that do not support run-time documentation queries, functions can be provided that return the documentation.
Tables of all OpenAL parameters and functions, as well as those of camlorn_audio itself, can be generated automatically.
The strategy for this is Jinja templates, JSON, Libclang, and a strange combinational approach between data and C++ code. That is, for manually generated things, I will interleave C++ and--probably--YML. The metadata will generate error checking, allowing documentation on it without intervention (again).
And yes, this is basically a compiler, minus the compiling. The compiling used to be the hard part, anyway. So far I've got macros. Macros and plans.
This is the 3rd part in my series on building an MMO, and it is no longer just an architecture. Basic game functionality has now been implemented: incredibly boring combat, the ability to walk between locations, and the ability to have persistent maps. Progress has slowed down, and these posts will consequently begin growing shorter and more broad.
This is the second part of my series on my attempts at an MMO architecture. I have an incredibly basic working game at this point, though it does have problems which I believe to be solveable. The entire program, both client and server, is currently 897 lines. I am going to outline the basic components below. I will also talk about my adventures with Unity3D, Unreal Developer's Kit, and a few other products. As always, this is a description of the current state of things. I may come back in part 3 and say I had to throw it all out, but at least there is something to learn from knowing that it didn't work.
Those watching me on Twitter are no doubt aware that I've been working on something. Last weekend was quite frankly the most productive I've ever had, and the net result was the very lowest level components of an online game. I have since taken it further, and stand at working terrain as of this posting.
I have decided that I will blog my progress, along with notes and information on the architecture as it develops. This means that I will no doubt have to say what changed, but I will of course post why it didn't work or what I gain from the new model. It is amazing how little information exists on this subject: there are some tutorials on making basic board games and sporatic information on how a real online MMO works, but nothing complete. I have worked a lot of this out myself or brainstorming with fellow developers, and very little of it by reading tutorials. The intent is that this will be an ongoing series, for as long as I maintain interest in writing it. Rather than jump straight in and say what I have currently, I want to start with my first two attempts and why they failed. I think this is important if only to provide some background. It also taught me why I shouldn't do certain things. It also taught me how to use Gevent, and succeeded in convincing me that Gevent is the right path.
Note that Christopher Toth (@mongoose_q on Twitter) is a co-programmer, but I've done 90% or more of the programming thus far. His advice and thoughts have been extremely hellpfull, and I can't take sole credit for my current success (but in all honesty I can take credit for my failures).
This is quite lengthy.
For those who don't know, about 3 weeks ago Unspoken was exhibiting some od behavior: sounds would sometimes, for some inexplicable reason, fail to load. As far as I can tell, this was something to do with NVDA, and seems to have fixed itself. I managed to find the error, but not the cause: Libsndfile sometimes decides that .wav files are actually raw audio files, and gets upset because no one tells it how to interpret them.
Needless to say, this was only happening in NVDA and not once outside of it. Since it's been gone for about 2 weeks now, I'm assuming it's gone permanently. If anyone sees it, let me know. The add-on will throw an exception if it happens.
For now, I'm declaring unspoken useable, but not 1.0. I've bumped the version to 0.1. You can find it here.
This is just a quick note on something that is going to hit people, and apparently already has.
I found out, indirectly, that others are trying to make NVDA add-ons that use Camlorn_audio. This fails. I am going to fix it shortly.
OpenAL makes it very hard to allow for the library to be initialized more than once. To do so in Camlorn_audio, a bunch of code is needed in a lot of places, and the approach would be very bug-prone, especially with streaming. It would probably also necessitate a global library lock.
Instead, I am going to make init_camlorn_audio no-op if called twice, and implement a way to check initialization status of the library. This should fix the problem. Long-term, I'm probably going to figure out how to make a Camlorn_audio script for add-ons that adds a 3d audio configuration dialog on import. This will give all add-ons the ability to share information and configuration options, so that we don't have 5 add-ons playing through 5 sound cards and so that there's not a race condition at NVDA start-up.
I'll post again when I've got an updated package that's safe for use in multiple NVDA add-ons. Expect this to be a week or so-it's mid-term week next week, so i'm incredibly busy.
As of now, I have taken over development of unspoken, the NVDA add-on replacing messages like "link", "menu", and so on with 3D sound. Bryan Smart gets most of the credit for this add-on, including credit for having the idea and coding it in the first place.
For those who don't know, this add-on uses Camlorn_audio to provide positional information about controls, as well as replace the slower spoken messages. Think Objsounds, only with 3d audio effects and, so i've heard, a lot less latency. If you are using headphones, you should be able to hear sounds on an imaginary screen in front of you; they move up and down as well as left and right. Future versions will allow changing some presentation options-the 3D effect is not quite enough for everyone, and some people want more or less reverb.
This version fixes the following major issues:
Battery life on laptops shouldn't nosedive when using Unspoken.
Unspoken should now work for those using NVDA in any language.
There is one bug left, but I cannot trigger it reliably. If you have an exception at start-up related to this add-on or if it suddenly stops playing a lot of sounds, keep your NVDA-log and send it to me. Restarting NVDA usually fixes it, and it happens very rarely. Unfortunately, it does not happen enough to be reliably debugged. Even more unfortunately, I cannot make it happen outside NVDA.
Note that the updater is disabled for now.
Anyhow, it is here.