Android builds now include libpng (over 10x speedup at PNG loading), new platformer release

Posted on

Platformer demo - jumping on higher platforms

Enjoy much faster PNG loading on Android now, as the libpng library is automatically packaged with your applications. Various measurements, like this one, or testing “The Unholy Society” UI loading time confirm that the speedup is huge, even more than 10x compared to previous FpImage that we used on Android.

In general, there’s no need to do anything for developers. The Android service “png” will be automatically added to the projects that include some PNG files in their data. But you can also request PNG explicitly (just for Android, or for all applicable platforms), follow the docs.

And you can enjoy a new faster level loading in our new platformer release on itch.io, that includes an Android (APK) build.

Comments on the forum ➤

FMOD sound backend improvements: spatial sounds, priority, distance model, offset

Posted on

FMOD logo

Our FMOD sound backend, that integrates CGE with the FMOD sound system, supports now 3D (spatial) sounds. This means that sound position in 3D is reflected in your ears — things that are closer are louder, things that are on your right are mostly in your right speakers etc.

The improvements outlined here make our FMOD sound backend at par (the same features, with the same CGE API) with our default OpenAL sound backend. This matters, as it opens the door for future integration with FMOD Studio. The goal of FMOD Studio is to make the work of sound designer easier. The sfx person can create sound effects in FMOD Studio, in a way that is agnostic to the game engine, and the code (like your game) simply sends “events” that may cause some sound effect (playing something, stopping something, fading in/out something…).

Note: OpenAL remains our default sound backend, as an open-source audio library, for our open-source game engine. The FMOD backend is just an option — when you are OK with using proprietary and commercial (though free in some cases, for indie devs) solution, in exchange for features like FMOD Studio and Nintendo Switch compatibility.

Our FMOD support improvements are:

  • We now pass to FMOD correct values of sound 3D position, velocity, listener 3D position and orientation, request right-handed coordinate system, and we set sounds to be spatial when appropriate.

  • The SoundEngine.DistanceModel is supported by FMOD (so you can change the distance model to “linear” if desired; default is equivalent to FMOD default, “inverse”).

  • The TCastlePlayingSound.Offset (reading and setting) works with FMOD.

  • Sound priority is now passed to FMOD in a more straightforward way, to allow FMOD to manage sound sources.

    CGE Priority (float in 0..1 range, higher is more important) is converted into FMOD priority (int in 0..256 range, lower is more important). Yeah, the word priority is inconsistent, and we cannot really win here — Unity, FMOD, Wwise, X3D… all have inconsistent ideas what does priority mean.

    If you’re curious about the decisions behind our TCastleSound.Priority definition, see this commit’s log. Sometimes it is just impossible to be consistent with everything… And inventing our own name for the same concept also felt wrong. We used the term Importance for quite some time, and it was documented as “This is a priority…” 🙂

  • Internal example moved to examples/audio/internal/fmod_api_test/ . This is a useful example for people that want to work directly with FMOD or extend our FMOD backend in CGE. It should not be followed by normal CGE users.

There’s no new CGE API to present here. Just use the existing classes like TCastleSoundSource and TCastleSound (see previous news post, about sound API upgrades). They will work with FMOD backend as you expect, producing 3D sound.

Comments on the forum ➤

New sound API (easier to use, more versatile) and ability to set up sounds using CGE editor

Posted on

Example 3D game with spatial sounds - TCastleSound
Example 3D game with spatial sounds - TCastleSoundSource
Example audio player using LCL for UI and CGE for sound playing
Example cross-platform testing of sound playback using CGE UI
Example showing Doppler effect
Editor Sound options
Desining a collection of sounds

We have a new shiny API to play sounds in Castle Game Engine!

I think it’s a major improvement over the previous API (that revolved around TSoundBuffer and TSound classes). The new API is easier to use:

  • It hides some internal constraints (a limited internal number of sounds that can be mixed simultaneously, or impossibility to change internal buffer contents/streaming after loading). You don’t need to care about that anymore.

  • The lifetime of instances is easier to grasp. You control the lifetime of everything, and there’s no need to deal with TSound.OnRelease.

The new API is also perfect to visually set things up in the CGE editor. It uses behaviors for spatial sounds.

The new classes, that you should use now for all sound loading and playing, are:

  • TCastleSound: The most important class, you should use this always when you want to play any sound.

    This is a new non-visual component that represents a sound file with some playback parameters. The most important properties are:

    • URL — undoubtedly the most important property, set this to actually load the sound file.

    • Stream — optionally use “streaming”, which is an alternative loading method best suited for longer playing sounds (like music tracks).

    • Volume — how loud the sound is. This is multiplied by volume at TCastlePlayingSound.Volume and TCastleSoundSource.Volume and by spatial calculations.

    • Pitch — sound playing speed. As with volume, the volume of TCastleSound.Pitch is multiplied by similar parameters controlled at TCastlePlayingSound.Pitch and TCastleSoundSource.Pitch.

    TCastleSound by itself doesn’t manage playing the sound. You have to use SoundEngine.Play to play the sound (the simplest way to play, for non-spatial sounds) or TCastleSoundSource (for sounds that can be spatial; assign to TCastleSoundSource.Sound for looping, use TCastleSoundSource.Play for non-looping).

    TCastleSound also replaces previous TSoundType (TSoundType is now an alias of TCastleSound). So reading sounds from sounds.xml file and using SoundEngine.SoundFromName just gives you ready TCastleSound instance. This XML file now becomes a new way to define “a list of TCastleSound instances”. Though you can also now ditch the manually-crafted XML files, and use a new approach we mention below — design a non-visual collection of components like all_sounds.castle-component.

  • TCastleSoundSource: A way to play spatial (3D) sounds.

    This is a behavior (see previous post) that enhances any TCastleTransform so that it emits (possibly spatial) sounds.

    TCastleSoundSource refers to TCastleSound for an actual sound information. You can set TCastleSoundSource.Sound (for looping). Or call TCastleSoundSource.Play (for non-looping).

  • TCastlePlayingSound: Optional, use if you need more control before and during the sound playback.

Both TCastleSoundSource and TCastleSound can be created, configured and linked in the CGE editor, e.g. when designing your state. You can hear the 3D sounds in the editor. You can also create and control them from code, as all CGE components.

All CGE examples have been upgraded to use the new approach for sounds.

  • See all the examples in examples/audio subdirectory.

  • In particular I recommend opening the examples/audio/game_3d_sound demo. Aside from using new sound API, it has also been recently upgraded to use CGE editor and glTF intensively.

  • See also examples/fixed_camera_game for a new approach to design a collection of sounds (a new, better approach than manually crafting XML files). In particular:

    • examples/fixed_camera_game/data/sounds/all_sounds.castle-component describes all sounds
    • examples/fixed_camera_game/code/gamesound.pas loads them

Editor sound features:

  • Sound volume, and “auto-mute on play” are now available in the editor settings.

  • Drag-and-drop sound files on the viewport to automatically create a spatial sound: TCastleTransform, TCastleSoundSource, TCastleSound.

  • You can manage a collection of sounds independent of state/UI by simply using TCastleComponent as a design root and adding TCastleSound children. Save the resulting design to a file like all_sounds.castle-component. This is a great alternative to previous XML files to describe sounds which will soon be deprecated most likely.

    You can see an example of using the new approach in examples/fixed_camera_game mentioned above.

Distance model changes:

  • Our previous default SoundEngine.DistanceModel was poor (linear, which is not realistic).

    Now it is dmInverse, and corresponds to FMOD default and OpenAL default. It’s the most natural model to play 3D spatial sounds.

  • Our default MaxDistance was poor (1, equal ReferenceDistance, which means that there’s no attenuation with linear model at all).

    Now MaxDistance is 10000 by default (like FMOD). ReferenceDistance remains 1 by default (just like in OpenAL and FMOD).

  • Our possible TSoundDistanceModel were not portable (they reflected OpenAL models closely, and did not reflect FMOD models).

    We limit ourselves now to actually useful models, supported by various sound backends (OpenAL and FMOD) now: dmInverse and dmLinear.

Backward compatibility:

The sound API upgrade described here is almost completely backward-compatible. Old classes still work, just make a warning about deprecation at compilation. The breaking changes are:

  • By default we use dmInverse model now, as it is much more natural for 3D sounds (and it is default in both OpenAL and FMOD too, for the same reason). If you want the same approach as in previous engine version, set SoundEngine.DistanceModel := dmLinear. Remember to adjust the TCastleSound.MaxDistance to sound good.

  • Our sounds XML file no longer supports “random aliases”. See the bottom of upgrading wiki page for explanation. I suppose it was quite obscure feature, not used by many, and maintaining it is just too much cost in new API. If you miss this feature, I released a small unit that allows you to bring it back into your game: use and adjust this in your projects.

We also made a fix for sounds defined in X3D files: 3D sounds defined using X3D nodes are now correctly played in world coordinates, i.e. loading an X3D scene with sounds inside TCastleScene, and then transforming this TCastleScene makes a proper sound effect.

Our manual chapter about sound has also been updated to reflect the information above. It’s admittedly very brief now, quite similar to this news post, but I hope to extend it into more tutorial-like description soon.

Comments on the forum ➤

Various asset improvements: Wavefront OBJ texture options and possible PBR, Spine free form deformation with curve animation, fixes for creaseAngle in X3D and OBJ

Posted on

Oak Wavefront OBJ model
Spine FFD animation test

Various improvements to various asset formats:

  • We now implement Wavefront OBJ texture options. They are all parsed correctly, and the scale, offset, clamp are actually handled.

    We can also generate PBR (physical) materials when reading Wavefront OBJ files. This feature is for now experimental, and you have to toggle global WavefrontPhongMaterial in X3DLoadInternalOBJ unit to false. In effect, we will create X3D PhysicalMaterial nodes from Wavefront materials, and we’ll use Pr for the PhysicalMaterial.MetallicRoughnessTexture. See the X3D specification of PhysicalMaterial for details what it implies.

  • We now support curve animation for Spine free form deformation. Thanks go to Kagamma (Trung Le) for implementing this!

    The testcase is in our demo-models, open spine/free_form_deformation/exported/skeleton.json and run head_curve animation.

  • Fixed important bug on all 3D models that could use automatic normals generation based on creaseAngle (like X3D and Wavefront OBJ by default).

Comments on the forum ➤

“The Unholy Society” release on Android and iOS

Posted on

The Unholy Society - NPC dialogue
The Unholy Society - woof
The Unholy Society - fight
The Unholy Society - tentacles
The Unholy Society - jerk
The Unholy Society - pope

We are proud to announce a mobile release of The Unholy Society, a game done by Cat-astrophe Games using Castle Game Engine!

The Unholy Society, the first part of a snarky exorcist’s adventures, is inspired by ’80s and ’90s movies, comic books, as well as everything else that fits into the categories of “iconic” and “pop culture”.

The story revolves around Bonaventura Horowitz – an exorcist who isn’t exactly an angel himself. At the request of the Pope, Bon, accompanied by a group of his peculiar friends, sets off on a thrilling mission, leaving behind a trail of cigarette butts, empty whiskey bottles, and broken demonic hearts.

The game is available on both Android (Google Play) and iOS (App Store). It is a free download, and you can play the prolog for free — afterwards you can purchase Act 1.

We hope for a great success on mobile, and we want to develop and publish further acts of the game. We have a cool story in the works.

P.S. If you’re a die-hard PC player, go ahead and grab the same game on Steam. Or on Nintendo Switch.

Comments on the forum ➤

Delphi porting progress — basic CGE window with images and text works!

Posted on

Castle Game Engine window rendered from Delphi
Castle Game Engine in Delphi
Castle Game Engine in Delphi

We have great news about Delphi compatibility with Castle Game Engine: We have basics (window, with images and text) working!

You can observe the work in this PR by Andrzej Kilijański.

Plans

The first goal is to make TCastleWindowBase with WinAPI backend working fully. This will make CGE working with Delphi for native Windows applications, using our advised approach (TCastleWindowBase). Of course more things will follow — we will want to have TCastleWindowBase running on other platforms supported by Delphi too (like mobile). And we will want to have TCastleControlBase that you can drop on FMX (and maybe VCL?) form too.

The immediate goal is now to enhance PR to include working JSON (which includes our serialization of designs) and then TCastleScene (which includes our most important rendering of 3D and 2D assets). Once this is done, most CGE examples will be compileable+runnable from Delphi.

Delphi versions

  • We target the recent Delphi versions, up to and including the latest Delphi 11 of course.

  • The port should work in principle on all Delphi versions with generics (>= 2009), though we may not be able to test it everywhere. But we’ll test at least on 10.4 and 11, and welcome anyone with older Delphi versions (but still >= 2009) to report.

  • Every variant (free Community Edition, paid Enterprise) will be supported and tested.

  • Note that we will not support ancient Delphi versions like Delphi 7. We’re aware some people use really old Delphi versions, but supporting these versions is not reasonable for us. It would require a serious effort to port code (e.g. generics) and then to keep testing every release with these old Delphi versions. In the end, Delphi 7 is really old. I advise everyone with Delphi 7 to either upgrade to the latest Delphi (the latest Community Edition is free, with some usage limits) or just switch to open-source cross-platform FPC/Lazarus.

Strings

We want the CGE API to be natural in Delphi, so the String type we use (when compiled by Delphi) is the default 16-bit Unicode Delphi string. Our font drawing (that has to deconstruct String -> sequence of Unicode numbers), and everything else, is adjusted to work with it.

Note: When compiled by FPC, we continue to follow FPC/Lazarus conventions: String is AnsiString and it just holds UTF-8 on all platforms.

(Sidenote: To be more precise, using UTF-8 everywhere is Lazarus/LCL convention. FPC AnsiString can use more complicated code-page aware mechanism. See 1, 2, 3, 4. Lazarus/LCL simplifies this (by adjusting some global vars) to “just use UTF-8 everywhere” and I think this is much simpler and thus better. It is also probably what many people expect (as a lot of FPC users are just Lazarus/LCL users). So we follow this in CGE too, setting the same global vars as LCL, to “just use UTF-8 everywhere”.)

So it’s a bit different between Delphi and FPC/Lazarus, but with the same goal: just follow the established default String meaning. Have the API natural for users coming from any compiler. For simple string usage from user code, this difference should not really matter — you write and glue strings as usual in Pascal, and both in FPC and Delphi the type and operators behave in a way that is natural.

External dependencies

For external dependencies (stuff specific to compiler and/or external to Pascal), we decide case-by-case on a best solution.

  • For XML stuff, we have a small wrapper to expose Delphi XML API in a compatible manner to FPC API. You can use this XML API in your own programs too (thus handling XML in a way that is compatible to both Delphi and FPC), but you don’t have to.

  • For URL stuff, we use FPC units with Delphi. (LGPL license of FPC RTL allows this.) This concerns units like URIParser. Majority of your code will use CGE API anyway, from CastleURIUtils and CastleDownload units, that of course work the same with Delphi and FPC.

  • For JSON — the decision will come (but preferably we’ll just use FpJsonRtti with Delphi, as it would be easiest). Your code will use CGE API anyway in CastleComponentSerialize (or even higher-level TUIState.DesignUrl) so it will not matter for you.

  • For FpImage — we will not use it with Delphi, instead relying on own image loading code (DDS, KTX, libpng for PNG etc.). It would be too cumbersome to try to pull whole FpImage into Delphi, and FpImage is not that important for us anyway (e.g. we load PNGs using libpng, without FpImage, due to FpImage being terribly slow; we load DDS and KTX without FpImage, as we need to load them efficiently to RAM and then to GPU, preserving compression like S3TC or ASTC).

Tools

Our first goal is to port the CGE runtime to Delphi — to make games using Delphi. The engine tools will mostly continue to be developed using FPC/Lazarus and they’ll just enable Delphi compiler as an alternative option. This means:

  • Build tool and editor will allow to use Delphi dcc under the hood, instead of FPC.

    Ideally, they’ll just auto-detect the compiler, by default. If you don’t have FPC/Lazarus installed, but you have Delphi installed, they should just use Delphi by default.

  • The editor itself will be compileable only by FPC/Lazarus, at least for now. As it seems not really reasonable to maintain it for both LCL and VCL/FMX at the same time, the differences are too much to maintain both versions in a painless way.

    This will make building editor with custom components on Delphi problematic at first. I mean, it will be possible — but you’ll just need an FPC/Lazarus for this, even if your game is using Delphi for the actual game build.

    We’ll be looking at better solutions for this. Maybe we’ll just have to figure out how to maintain editor that compiles with both LCL and VCL/FMX. But we have to experiment how to have it without a big maintenance burden (we do not want to just fork the editor for VCL/FMX, as it would not be maintainable in the long run).

Comments on the forum ➤

Support for new iOS launch images, better loading image scaling

Posted on

Castle Game Engine launching
  1. We support a new way to define launch images on iOS. Launch images are something displayed by the iOS when the application is, well, launching. They are displayed immediately when you click the application, before any CGE code (even Objective-C code) has been run. Their point is to communicate to the user “the application is launching, please wait”, so that the (usually very short) delay when the application launches is not a problem (user will not look confused at the screen, wondering whether (s)he clicked the screen OK etc.).

    We now have a better way to define them, using a better mechanism called launch image storyboard. It is documented as part of CastleEngineManifest.xml. Just place something like this in your CastleEngineManifest.xml:

    <launch_images>
      <storyboard 
        path="launch-image.png"
        scale="1.0" 
        background_color="000000"
      />
    </launch_images>
    

    The advantages of the new system are: you can provide your graphic with any size (it will be resized to fit any iOS device nicely) and it works in iPhone landscape nicely (just like in portrait, of course).

    It’s also the advised way to define launch images on iOS now. You can ignore the iOS warnings from Xcode about the fact that we use the old (deprecated) approach to the launch images as well — for now we use both methods (old and new) for launch images, to work always, but in the end we’ll just remove the old approach.

  2. In a related department, we have made it more flexible how our CGE “loading” image is displayed. This is the image displayed by CGE while the Application.OnInitialize is being executed. (So it happens after launch images, in case of iOS.)

    See the 6.1. Adjust loading image for a description how to set this image.

    We now expose Theme.LoadingUIScaling, Theme.LoadingUIReferenceWidthg, Theme.LoadingUIReferenceHeight to define how is the loading image scaled. You can set these properties to match the UI scaling settings in your CastleSettings.xml, and thus have loading image scaling matching perfectly the following CGE UI. This may be useful to seamlessly fade-in some splash image once your game actually starts.

    In the future I plan to automate this even more. We should allow to auto-generate Pascal code that defines the loading image, and so the synchronization with CastleSettings.xml will just happen automatically.

Comments on the forum ➤

Fixes to FreeType and VorbisFile dependencies, new Platformer release (now on Android too)

Posted on

Platformer demo - title screen
  • We now gracefully tolerate:

    • Missing VorbisFile library. If missing, we will just not play OggVorbis files, but otherwise everything will work.

    • Missing FreeType library. If not available, texts will be rendered using the standard UIFont, instead of being invisible.

    It has been always our intention to tolerate missing external library dependencies as much as we reasonably can. Because “in the wild” there are many reasons why dynamic library may fail to load (some of them under the control of the developer, some not), so it’s best to tolerate these failures nicely.

    Of course they are reported using warnings (watch log), and as a developer you want to make sure to package your library correctly. But we want to tolerate here mistakes — a game without music is better than a game that crashes at start for user.

  • We have fixed the automatic packaging of FreeType and VorbisFile DLLs on Windows. We added their necessary Visual C++ Redistributables dependencies (vcruntime140.dll, msvcr120.dll). The build tool and editor will automatically place all necessary DLLs alongside your EXE when building a Windows application.

  • We have released a new version of our Platformer demo. It is now available on Android. Also the Windows build includes the Visual C++ Redistributables previously missing.

Comments on the forum ➤

Better packaging and installing from editor

Posted on

Choosing package format in the editor
  • Using F9 when Platform is Android in editor now “just works”. That is, it will execute package + install + run. So it will rebuild and run the project on your connected Android device (assuming you have installed Android SDK and cross-compiler).

  • You can now choose the package format (zip, tar.gz, Android APK, Android AAB etc.) in the editor.

  • Better treatment of “package format” throughout build tool for “package” and “install” commands. The “install” build tool command now takes --package-format argument too.

  • The “install” on Android fixed, to look for APK with proper name.

Comments on the forum (1) ➤

Documentation about implementing in-app purchases on mobile (Android, iOS) and creating custom components

Posted on

In-app purchase question (in Polish)

I have documented how to implement in-app purchases on mobile (Android and iOS) on In-app purchases (wiki page). This is a much updated and extended version of what was previously in the TInAppPurchases class API docs.

(A complete example showing this will follow later too.)

Another new useful documentation page is how to create custom components. For this, the primary example is in examples/advanced_editor.

Comments on the forum ➤