Editor gizmos improvements: XY movement comfortable for 2D games and 2 important fixes

Posted on

Gizmo in 2D game

We improved behavior of gizmos (for translating, rotating, scaling TCastleTransform in the editor):

  1. The translation mode is more comfortable for 2D games. When you have typical 2D projection (orthographic, and camera looks along -Z axis) then

    • clicking on a special box in the middle of the gizmo,

    • or clicking on the Z arrow (previously a useless blue dot in case of such typical 2D projection)

    … allows to move the object simultaneously in X and Y. This allows to just move the object in 2D freely. This is done thanks to Andrzej Kilijański!

  2. Fixed a case when translation may behave a bit crazy when the transformation had both rotation and non-uniform scale applied.

  3. Fixed imprecise calculations (that caused the gizmo size to “tremble” sometimes) when using on a scene with large bounding box.

Comments on the forum ➤

Occlusion query (documentation and fixes)

Posted on

Occlusion Query

We now have an extensive docs about occlusion query in Castle Game Engine.

We also fixed occlusion query for shapes with blending, and made it behave correctly when batching is used (right now, batching has to be disabled for the scenes that use occlusion query).

On a more general note: Sorry for the relative silence in the news in last 2 weeks. We’re busy making a few things at once, big (memory optimizations, Delphi compatibility, docking editor) and small (Android x86, editor gizmos improvements). I will gradually post about them 🙂

Comments on the forum ➤

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 ➤