Creating OpenGLES 3 context on mobile

Posted on

Gallery of Particle System

We now load OpenGLES 3 context on mobile when possible (but still fallback to OpenGLES 2).

Core Castle Game Engine for now doesn’t actually use any OpenGLES 3 functionality. But we make available SetTransformFeedbackVaryings for shaders, which can be utilized by components like Particle Emitter (particle system for 3D and 2D in CGE) to now work on mobile.

Many thanks go to Trung Le (Kagamma) for implementing this!

iOS note

We made it work for both Android and iOS. But then we disabled it for iOS, at least for now.

Because it caused a small regression in Unholy Society — sometimes using FBOs causes a weird shift in further display. This was observed only on iOS + OpenGLES 3 (same code works OK on everything else: OpenGL on desktops, Android with OpenGLES 2 and 3, iOS + OpenGLES 2). Evidently Apple didn’t make the OpenGLES 3 truly backward compatible with OpenGLES 2. If you want to try it anyway (everything else works, the regression likely doesn’t affect most applications), adjust the code responsible for context creation on iOS in tools/build-tool/data/ios/xcode_project/cge_project_name/OpenGLController.m. You want to use this:

    EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
    if (context == nil) {
        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    }

Further details about this will follow. Ideally we want to workaround this problem at CGE level, and just create OpenGLES 3 context on iOS by default, same as on Android. If this will be impossible, we’ll give you a choice whether to try creating OpenGLES 3 context on iOS in CastleEngineManifest.xml.

Comments on the forum ➤

Delphi Port Progress – window, UI, designs (JSON) serialization, XML compatibility, Delphi 11 / 10.4, Windows 32 and 64, PNG using PngImage

Posted on

state_events example using Delphi
TCastleEdit in Delphi
Various UI controls using CGE in Delphi
test_all_state_events example using Delphi
TCastleTimer in Delphi

We made great progress porting Castle Game Engine to Delphi.

  • Running an engine in a window (using TCastleWindowBase) on Windows works.

  • User interface controls (things in CastleControls, CastleUIControls units, like buttons, images, edit boxes etc.) all work.

  • Reading and writing design files, like .castle-user-interface, that you create using CGE editor works. We’re using a version of FpJson and FpJsonRtti from FPC, with minimal adjustments to make them compile in Delphi.

  • Examples from examples/user_interface now work in Delphi.

  • XML compatibility much improved. This gives us compatibility layer to access XML in Delphi using similar classes as we use in FPC DOM and friends.

  • Tested now on both Delphi 11 and 10.4.

  • Tested now on both Windows 32-bit and 64-bit.

  • Reading PNG has a fallback on built-in PngImage unit available in Delphi. This is used if libpng DLL is not available at runtime.

See the previous news post for all plans about Delphi port. Everything described here is public of course, you can take a look at how it works already: see the pull request. In particular you can try it yourself, just take delphi branch from Andrzej Kilijański’s CGE fork.

Comments on the forum (1) ➤

Arch Linux package

Posted on

CGE editor on Arch Linux

Arch Linux users can now install Castle Game Engine from AUR (Arch User Repository).

The package is available on https://aur.archlinux.org/packages/castle-engine-git/ . Follow the standard AUR installation process:

  • Do it manually following AUR docs, like

    wget https://aur.archlinux.org/cgit/aur.git/snapshot/castle-engine-git.tar.gz
    tar xzvf castle-engine-git.tar.gz 
    cd castle-engine-git/
    makepkg -sri
    
  • Or use a helper like paru. Once you have it working, just use paru -S castle-engine-git.

Thanks go to Kagamma (Trung Le) for doing this!

Comments on the forum ➤

Google Play Billing Library upgrade

Posted on

unholy_iap

To implement in-app purchases on Android, under the hood we use Google Play Billing Library. We have just upgraded the way we use it, to follow the latest API (no AIDL, and use built-in asynchronous methods).

This is important if you use in-app purchases on Android. Since November 2021 (in one month) Google will no longer allow uploading Android builds (APK, AAB) that use the old API.

There’s no change to the Castle Game Engine public API. Just use the Pascal unit CastleInAppPurchases, following the documentation how to implement in-app purchases on both Android and iOS. Both consumable and non-consumable in-app purchases are supported.

The Unholy Society is already using the new API for our only purchase in the game.

Comments on the forum ➤

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 ➤