Looking at Delphi game development with Asphyre
Delphinian pointed out two Delphi game-development SDKs I hadn’t known about: Pyrogine and Asphyre.
I’ll ignore Pyrogine, since it’s still vaporware at this point — nothing available to download. But Asphyre has some possibilities.
Editions of Asphyre
Asphyre comes in four different flavors, and they don’t try very hard to help you figure out which one you should use. As far as I can tell, though, it comes down to this:
- If you want bleeding-edge 3D effects, use Asphyre 4.1. It’s not yet release-quality (all they have are snapshots) and it always requires the latest and greatest version of DirectX.
- If you want something more stable, and don’t mind requiring DirectX 9, use Asphyre eXtreme. It’s billed as their “most stable” version.
- If you don’t want to require DirectX 9, use Asphyre Casual or Asphyre 1.5.2. Asphyre Casual is not yet release-quality (all they have are snapshots). Asphyre 1.5.2 is an older version and is no longer in active development. Take your pick.
Asphyre eXtreme looks like it’s probably the preferred choice for most applications.
Asphyre license
Asphyre is open-source, released under the MPL.
This makes it a much better choice than (un)DelphiX, which has a license agreement saying it’s illegal. So I’ll definitely be looking at using Asphyre going forward.
Concerns
The big downside I see so far is that Asphyre clearly wasn’t written by experienced Delphi developers.
- They don’t throw exceptions. They don’t even return numeric error codes. Everything is Boolean result codes: “it worked” or “it didn’t work”. With a rich exception system just waiting to be used, it’s pretty inconsiderate for them to give such crappy feedback, especially with something like DirectX where poor drivers can make so many things go wrong.
- They don’t seem to have heard of try..finally. As a rule, they don’t do any resource protection. (This may be because of the previous point, but it’s still pretty sloppy coding style.)
- They seem to like using global variables to hold non-global state. To take one specific example, the “Basic” sample project, in the Asphyre Casual package, stores form state in a unit full of global variables. Shouldn’t form state be on the form?
Less damning, but just as interesting, is the way they don’t follow common Delphi coding standards. They indent blocks by one space instead of the usual two. They clutter their code with empty parentheses after method calls and declarations. They don’t prefix field names with F. They don’t use FreeAndNil. In short, they don’t seem to have spent any time looking at Delphi code.
But…

they certainly can do graphics.
February 12th, 2008 at 7:52 am
It’s not easy to learn, but is a great library once you do.
February 12th, 2008 at 10:48 pm
Downloads are now available. We are still in beta at the moment, but things are pretty solid. Lots of great features we hope to get in the 2.0 release.
February 13th, 2008 at 12:52 pm
1) “They don’t throw exceptions.”
This has been discussed to death on PGD. Read thread named “Error handling considerations”.
2) “They don’t even return numeric error codes.”
This is how older versions of Asphyre did it. However, if you want to “seriously work with Direct3D” my friend, you’d be using debug runtimes.
3) “They seem to like using global variables to hold non-global state.”
Nonsense. Direct3D device *is* global, and it has nothing to do with VCL. Same applies to other Asphyre components, which are stored as global variables.
4) “To take one specific example, the “Basic” sample project, in the Asphyre Casual package, stores form state in a unit full of global variables. Shouldn’t form state be on the form?”
Where did you see “form state”? They are all variables related to Asphyre, which is unrelated to FORM and/or VCL in any way.
P.S. The coding style is propietary. It’s not cluttered, it’s just happens you don’t like it.
When you are talking about the “experience of Asphyre developers”, please search on Google the following article:
“Unskilled and Unaware of It: How Difficulties in Recognizing One’s Own
Incompetence Lead to Inflated Self-Assessments”
It will help you improve the quality of your reviews.
February 13th, 2008 at 11:12 pm
Lifepower,
Cool. I’d love to read more about this. But it would help if you could give me some idea of where to look.
I took a guess that your reference to “PGD” might have meant “pascalgamedevelopment.com”, but there aren’t any threads in their Asphyre forum with “error” in the title. I couldn’t find anything in the afterwarp.net forums, either. And a Google search for
error handling considerations site:pascalgamedevelopment.comturned up nada, as diderror handling considerations asphyre.Could you post a URL or something?
Could be. I know very little about the DirectX debug runtimes at this point. Although I don’t quite see how they would make Asphyre return anything more interesting than False.
And they wouldn’t do any good when someone else tries to run my program. With no opportunity to get anything more meaningful than Boolean result codes, I expect any problems would be a bitch to troubleshoot.
Hmm. Then why was I just able to whip up a proof-of-concept that put two (un)DelphiX TDXDraw instances on the same form? Not to mention the possibility of multiple forms (MDI and/or SDI).
In fullscreen mode, yes, it might as well be global. But in windowed mode, not so much.
Form size (DisplaySize). Classes used to draw on the form (GameDevice, GameCanvas). Variables that are populated by the form, only used by the form, with the same lifetime as the form.
I will grant you that Asphyre is GUI-library agnostic. I hadn’t thought about that angle, and I can see using globals to make the code more easily cross-compilable to other libraries. (Although if that was the goal, wouldn’t all the drawing code live outside the form, too?)
I do still dislike the globals, but if the reason is easier cross-library compatibility, then that becomes more of a personal preference. There are other ways to do it, but globals do have simplicity going for them.
I suppose that’s fair. But it’s not a coding style that Delphi developers would find familiar.
February 17th, 2008 at 10:32 am
Ok, let me go in detail.
“They don’t throw exceptions. They don’t even return numeric error codes”
Throwing exceptions in full-screen Direct3D app will ruin your app and your IDE (when debugger is enabled) and you won’t be able to save your work. Exceptions inside the framework increase Coupling, so you will need to know more about internal working of Asphyre in order to handle its errors properly. Thus, exceptions were not used.
Many Direct3D calls silently fail and the error code is usually given later on. In most cases, Asphyre intercepts and handles known failures. Also, it is usually easy to determine the cause of error depending on what method failed. Finally, Direct3D debug runtimes give all the necessary debug information for each method and each failure, in detail. End users don’t need to know this as their technical level is probably much less than yours. Thus, numerical values are not used. Check our game Wicked Defense to see how errors are handled.
“They don’t seem to have heard of try..finally. As a rule, they don’t do any resource protection.”
You haven’t explained what you meant by “resource protection”. As for “try..finally” - read above about exceptions.
“Then why was I just able to whip up a proof-of-concept that put two (un)DelphiX TDXDraw instances on the same form? Not to mention the possibility of multiple forms (MDI and/or SDI).”
Your argument is still very weak. Direct3D needs window handle to present the final rendering on some surface, however, this handle can be changed at any time and thus is independent of a particular instance of TForm, not to mention that technically, it needs to know nothing about Delphi’s TForm class. (un)DelphiX does things differently and is heavily dependant on VCL, whereas Asphyre is not. Suffice to say that Asphyre can be used in FPC/Lazarus, while (un)DelphiX cannot.
“Form size (DisplaySize). Classes used to draw on the form (GameDevice, GameCanvas). Variables that are populated by the form, only used by the form, with the same lifetime as the form.”
DisplaySize is the rendering surface size and is independent of form size. Try resizing the form and you will see your rendering rescaled to fit new size.
The form creates these variables as in Factory Pattern. The variables are not necessarily used by the form itself (in Asphyre examples they do for simplicity of code).
Ideally, Asphyre components must be placed in a separate class called TGraphicsCore. This is an ideal architecture.
“I do still dislike the globals…”
Apparently, your whole review is based solely on pure personal taste. You could as well write about how you dislike eating apples or oranges.
Just because you like or dislike something does not mean that a certain feature is badly used. In fact, it makes your review biased and less objective.
I tried my best to clarify few things to you politely even though you have shown a certain arrogance and disrespect to Asphyre developers.