Auto-reloading (hot reloading) when the game runs, and more things auto-reloaded at design-time

Posted on

Hot reloading images at run-time (when the game runs)

When working in the editor, we now automatically reload images and Tiled maps when they change on disk. This means that you can edit image e.g. in GIMP, save it, and just Alt + Tab back to the editor to see the new image displayed as part of UI or in the viewport. Similarly, you can edit and save the map in Tiled and just switch back to the editor to see the new map.

This is in addition to our earlier feature of auto-reloading the scenes when the change, which allows to e.g. edit in Blender, export to glTF and then immediately see the update in CGE editor.

To be precise, components that now support automatic reloading are:

To take it a step further, you can enable this automatic activation also at run-time (when the game actually runs)! This allows to develop and test your game “live”, right as it runs. E.g. tweak a scene with 3D enemy, right when you actually see the given scene in the game. Or tweak an image right when you actually see it appear in the UI.

To enable this, enter the inspector (press F8 on desktop, by default) and select the checkbox “Monitor and Auto-Reload Data”. If you don’t see this checkbox, make sure you have regenerated your project files using the latest engine version.

Warning: Reloading the content at run-time cannot be a 100% safe operation in all the cases. In general, your project code may make assumptions that are true in “normal” project usage, but will be broken by reloading the image or scene. For example:

  • Reloading image components means that image size may change in the middle of work. If you have been using the image size in some calculations, that calculation has to be redone now.

  • Reloading TCastleScene means that all X3D nodes are freed, and then loaded back from file. If you have done some post-processing of a loaded scene, this will be lost. If you have saved some references to nodes (TX3DNode instances in MyScene.RootNode), they will be invalid after reloading.

    You could make these scenarios work, e.g. observe for node release using notification mechanism like TX3DNode.AddDestructionNotification or AnyNodeDestructionNotifications to set freed references to nil. Then reinitialize them on-demand. But it is completely understandable that you may also just ignore this issue — auto-reloading should not happen when regular users play a release version of your project. And the extra code to account for hot-reload could be an additional complication. It is your decision whether/when it is worth it.

  • For the above reasons, we have also disabled for now “auto reload” for reusable designs (in TCastleDesign and TCastleTransformDesign, see reusable designs). Auto-reloading them could cause too many problems, since in most cases you keep references to some components inside loaded designs in your code — these references would become invalid.

    Although it is almost implemented.. but commented out. If you want to experiment, go ahead and test uncommenting it in castletransform_design.inc (for TCastleTransformDesign) and/or castlecontrols_design.inc (for TCastleDesign). I welcome feedback — if you feel that this feature is more useful than it is dangerous, we can make it active. Or introduce a 2nd checkbox like “Monitor and Auto-Reload ALL Data (dangerous!)”

This feature was inspired by Tomorrow Corporation Tech Demo. It’s quite amazing demo cranking such “hot reload” features “up to eleven” πŸ™‚ Very advised to watch and be inspired!

Note: There are some known missing pieces related to reloading. Nothing is ever perfect πŸ™‚ Comments and encouragements to extend this are welcome as usual. And this feels like a good place to remind that we cherish your support on Patreon – please support us if you can. Thank you!

Comments on the forum ➀

Regenerate Your Project for better Debug / Release settings in both Lazarus and Delphi (and to be prepared for secret features coming next week)

Posted on

Regenerate Your Project

The summary of this post is: Download latest engine and use “Code -> Regenerate Project” menu item in the editor. It will regenerate the files inside your project (DPR, LPI, DPROJ, and CastleAutoGenerated.pas unit).

We’ve made a few improvements to them, and all together it means we strongly advise you to regenerate your project. The improvements are outlined below, though their real “big outcome” is to unlock 2 new features I will announce in further news posts πŸ™‚

Notes:

  • As always, using the “Code -> Regenerate Project” is not strictly required by us.

    Just recommended, esp. if you develop a regular game following our “New Project” templates, and most examples, as seen in cross-platform manual. In such case, we advise you let us auto-generate your project files (as above: DPR, LPI, DPROJ, and CastleAutoGenerated.pas unit) and you only focus on putting code in units (like gameinitialize.pas, views, and of course as many additional units as you need).

    But if you develop something non-standard (like a Lazarus LCL or Delphi VCL / FMX application using TCastleControl) then you may prefer to manage the project yourself, manually. That’s cool too, engine will work perfectly, you will just have to activate some features explicitly, like starting logging (by InitializeLog) or debug features (by ApplicationProperties.InitializeDebug).

  • Note that you can also do this from command-line: run castle-engine generate-program.

  • As always for development, we recommend you have a backup, actually use a version control (like GIT, backed by a server like GitHub or GitLab) and check the differences caused by the regeneration. If you’re not using version control yet, you really should start :), there are lots of self-hosted and “cloud”-hosted options, also free, even for private (not public) projects.

After this long introduction, the things we improved:

  1. Newly generated Lazarus (LPI) projects include Debug / Release build modes, that set common optimization/debug flags and define DEBUG / RELEASE symbols.

    This is consistent with what our build tool has been doing since ~always and how we configure Delphi projects.

  2. The CastleAutoGenerated unit now calls ApplicationProperties.InitializeDebug or ApplicationProperties.InitializeRelease depending on the DEBUG define when compiling the project.

    This means we can do some stuff (like enabling inspector on F8 key, or file monitor — see future news!) regardless of whether the engine units were compiled with the DEBUG symbol or not.

    The idea is that the DEBUG symbol definition when compiling your project should matter, and the DEBUG symbol definition when compiling the engine should be something independent.

    Why? This allows to have pre-compiled engine, and the same engine (so, release) available for both debug and release projects. Right now compilation from our build tool actually compiles the engine and your project in the same mode (both are debug or both are release), and our advised Delphi compilation does the same. But it’s not going to be like this always. Compilation from Lazarus IDE using packages is already different: engine Lazarus packages are compiled with options independent from your project. Future Delphi integration may also mean you use engine units compiled once, from all projects.

    So we are getting ready for this, by “cleaning up” our debug/release relations between project and engine.

  3. We fixed mixed-up Debug and Release settings in auto-generated Delphi (DPROJ) files.

    By a mistake, since a few months, the DPROJ files we have auto-generated had DEBUG and RELEASE options mixed up.

    That is, when you selected “Debug” from Delphi, we actually made a release build (with optimizations and with RELEASE compilation symbol). Conversely,Β when you selected “Release”, we actually made a debug build (without optimizations and with DEBUG compilation symbol defined). I know, silly bug, we just caught it. Sorry — but at least you can fix it with literally one click, just regenerate project.

    This is connected to the inspector (invoked by F8): It means that our debug build didn’t react to F8, while release builds did…Β Fixed now. Inspector (F8) is active in debug builds now.

As usual for a long post without clear thing to screenshot, I just show something pretty πŸ™‚ The screnshot comes from Cyberpunk City (old project) by carlcapu9 licensed under CC-BY-4.0.

Comments on the forum ➀

Spanish translation of our tutorial “Bad way to play chess: 3D physics fun using Castle Game Engine”

Posted on

Bad Chess - physics acting

Today we have a treat for our Spanish users: our latest tutorial Bad way to play chess: 3D physics fun using Castle Game Engine is now available in Spanish!

Read it here:

  1. Part 1 (installation, using editor, testing physics…).

  2. Part 2 (coding).

Big thanks for this go to Jorge Turiel (aka BlueIcaro) and his blog where he frequently writes about Pascal and our engine. I’m sure you will enjoy this if you read Spanish, so be sure to check out the tutorial — highly recommended reading, this is our latest tutorial that is right now the best introduction to using the engine, showcasing all important engine features.

If you have any questions in Spanish or just wanted to say thank you to Jorge, please use the “Comments” section at the bottom of every linked article! And share the links with your fellow Spanish Pascal and Castle Game Engine users πŸ™‚

In related news: I have rearranged our main page linking to this tutorial, to clearly link to all article versions, including the new Spanish. If you’d like to translate the tutorial to your language, we welcome it! Every approach is good. For example, you can host the translation on your own blog, if you so desire, just like Jorge does, and organize your local community. Or you can submit PR to our bad-chess repo, adding localized article versions inside the article/ subdirectory, like castle_game_engine_bad_chess_1_polish.adoc. I (Michalis) will then take care to review and link it everywhere.

Thank you everyone for together spreading the knowledge about our engine!

Comments on the forum ➀

Updates to Modern Object Pascal Introduction – anonymous functions, generic collections sorting

Posted on

VS Code with Pascal example of anonymous functions

We have updated our Modern Object Pascal Introduction for Programmers. Enjoy!

The most important addition is the section about “Anonymous functions”. It’s mostly just a simple example (tested to compile with both FPC and Delphi) along with links to good Delphi and FPC documentation. The examples are also in the repository:

The above examples probably do not really do “justice” to demonstrate anonymous functions capabilities. The big thing is that, as you can write the body of anonymous function inside a larger context, you can access the variables from that context. This means that there’s less need to invent “how to pass additional data to a callback”, which is a common need when using normal callbacks (to global routines or methods) that requires adding new fields or even classes that are useful only temporarily. Various details of this mechanism are documented in Delphi documentation (and the FPC implementation is compatible, from what I know).

While we cannot use the anonymous functions in CGE code (as we want to stay compatible with FPC >= 3.2.0, while anonymous functions are only in unstable FPC 3.3.1 for now). But there’s no reason why you couldn’t use them in your own projects, if you use Delphi or FPC 3.3.1. To install FPC 3.3.1 we recommend FpcUpDeluxe. In the CGE editor preferences, you can point to the FPC version you’d like to use, choosing any installation done by FpcUpDeluxe.

Another update is fix to Generics.Collections example showcasing sorting using custom comparer. Recent FPC versions change the required parameter type from constref to const (for Delphi compatibility as well as better code generation).

We have also updated the scripts of modern-pascal-introduction to ease updating everything when the content changes, and defined GitHub Actions to check that all code samples build correctly.

Comments on the forum ➀

Shader Effects on a Texture

Posted on

Shader Effects on Texture

First of all, sorry for a relatively silent last month when it comes to the Castle Game Engine news. It was actually an incredibly busy June, and I’m going to prove it by posting lots of news in the upcoming days πŸ™‚

Let’s start with a new example, Shader Effects On Texture (examples/viewport_and_scenes/shader_effects_on_texture). This example demonstrates how you can process colors (and alpha) coming from a texture using a shader, for basically any processing that is conceptually “I wish this texture would look like this”. For example you can tweak texture colors, you can perform any texture transformation, you can mix the texture with basically anything (like another texture or an animated effect), you can calculate some channel based on others (e.g. calculate alpha based on intensity of RGB colors). At the core, you just write a shader using GLSL that defines a function with magic name PLUG_texture_color, so it’s really simple to start with some 1-line snippet, but you can explode it to do any crazy effect that GPU can handle πŸ™‚

The interesting Pascal code of this example is rather simple and limited to the GameViewMain unit, it comes down to processing the scene, finding textures (TAbstractSingleTextureNode instances), and adding the effects. You can add any effect to any texture in any scene. The possibilities for tweaking this to your needs are vast:

  • You can apply the effect to any scene / scenes,

  • You can apply the effect to any textures there (to detect which texture is which, use e.g. TAbstractTexture2DNode.TextureUsedFullUrl once the texture is loaded; set TAbstractTexture2DNode.IsTextureLoaded to true to force loading it now; use TImageTextureNode.FdUrl to look at specified possible URLs of the texture; as you can see there are a few useful texture classes involved, take a look at TImageTextureNode and all its ancestors for all the goodies),

  • You can add multiple effects, no problem. The PLUG_texture_color function name is “magic”, as mentioned before — you absolutely can have multiple effects using it on one texture. The engine will internally transform it into a working shader code, integrated with full shape rendering code.

  • If you would like to ignore the original color read from texture image, sure -> you can.

    We also have a dedicated TShaderTextureNode class, which is a special texture class that does not read its contents from any image, and it’s great if you would like to just “invent” texture contents, procedurally generating it in the shader, based on anything — like a noise equation. TShaderTextureNode is great to define something that is a regular texture for all engine functionality (e.g. can get texture coordinates), yet it’s completely “invented” by the shader code.

As always, follow the README of the example to know all the details.

See also the associated Using Shader Effects to implement rendering effects that enhance the standard rendering (examples/viewport_and_scenes/shader_effects). It shows applying shader effects over shapes and scenes, independently of the textures. All the possibilities are in Shader Effects (Compositing Shaders) documentation, in particular see Reference of available plugs to know all magic PLUG_xxx functions.

As always, have fun and we ask for your support on Patreon! I hope we’ll all have a very fun, and very productive vacation πŸ™‚

Comments on the forum ➀

Many engine improvements on the road to next release: TCastleShape outlines, VS Code integration improvements, decide which viewport controls listener, packing to zip easier…

Posted on

Flying Cthulhu from Sketchfab https://sketchfab.com/3d-models/flying-cthulhu-4737a3b84e00415b9d8bb42ae44285b2 by TooManyDemons

As you can see from our increased frequency of news posts, we’re busy busy doing lots of things around the engine πŸ™‚ The primary goal is to push engine 7.0-alpha.3 release out, with the bigger goal on the horizon to finally reach the mythical engine 7.0 release. And then of course do more things, planned after 7.0, like the web platform. As much as I like talking about our roadmap, I like doing it even more!

Remember that we’re listening for your feedback on our forum, Discord, GitHub issues, Reddit, Patreon and everywhere else we can.

And we appreciate if you can support us on Patreon — this is what ultimately allows us to commit more resources toward the engine!

So below, another bag of engine improvements “all across the board” — everyone may find something to enjoy below πŸ™‚ They are all already available in latest engine downloads which are now snapshots, built from latest GitHub code.

  1. TCastleShape more functional: Outline, Filled and related properties undeprecated and implemented for triangles too.

  2. Our LSP server improvements (no more spamming with errors in case of include file without {%MainUnit xxx.pas}.

  3. VS Code extension improvements, in particular fixed behavior with bundled FPC on Linux.

  4. TCastleThirdPersonNavigation fixes and API documentation improvements to work better in case your avatar has non-standard orientation.

    Note that new navigation components are coming, as part of PR 533. But we are committed to maintaining TCastleThirdPersonNavigation for a few releases too — as migrating to new navigation components will not be an automated process, they present quite a bit different API.

  5. TCastleViewport.UpdateSoundListener added, to indicate which viewport controls sound listener. Esp. useful when you have multiple viewports.

  6. Tiled improvements — when when we have a tileset without image atlas (not yet supported, but at least gracefully ignored now).

  7. projector example important fix (do not stretch the texture where it shouldn’t be).

  8. ApplicationData deprecated, and simplified (returns castle-data:... now). This also means that now

    FindFiles(ApplicationData('something'), false, @FoundIndex, nil, [ffRecursive]);
    

    will work, also on Android. But also, compiling it will clearly encourage you to use castle-data:/something instead.

  9. Removed old deprecated physics components (TRigidBody, TCollider) as they could confuse new engine users, and there was now plenty of time to upgrade πŸ™‚ See physics for description of our physics components.

  10. Packaging to zip is now more reliable: we no longer depend on external zip executable, on most platforms we will use built-in code that packages to zip.

  11. We now specify program name in DPR, to avoid Delphi IDE from breaking code when adding new units.

Comments on the forum ➀

New example demonstrating a few possible animations optimizations

Posted on

Optimize animations

I added a new example showcasing various engine features you can enable to optimize how animations are processed. It is present in examples/animations/optimize_animations_test subdirectory of the engine. Enjoy!

Make sure to make a release (not debug) build to experiment with performance. On my system, I can make FPS between 15 and 60 (which is maximum with vsync=on for my system), depending on the configuration of the switches. So there’s a nice spectrum to show how various options improve the speed.

Read the API reference of the linked options for details — what these things do, when do you want to enable them (and when not):

  • OptimizeExtensiveTransformations and InternalFastTransformUpdate — both especially useful in case of nested transformation hierarchies when many transformations change every frame. Like typical animations done using skeleton, in Spine or glTF. In the future, I hope to be able to actually remove both these flags, and have their respective optimizations always “on” and universal (always beneficial, never losing any functionality)

    I have also fixed OptimizeExtensiveTransformations along the way of preparing this — it had a long-standing bug that prevented from using it. Now it’s all good.

  • TCastleViewport.DynamicBatching also helps, though it is really a rendering optimization (doesn’t affect how animations are processed).

  • TCastleSceneCore.AnimateOnlyWhenVisible does pretty much does what it says :), it only optimizes animations if you look away from them. The invisible animations are not updated, saving time. You can experiment with this by looking away (press right mouse button to activate mouse look in the example).

  • TCastleSceneCore.AnimateSkipTicks is a “brutal” optimization — if you set it to something > 0 then animation just doesn’t update every frame. In this example you can toggle it between 0 (don’t skip) and 1 (skip every other frame). You can experiment with setting it to something even larger, like 2, for even more performance but sacrificing quality.

Comments on the forum ➀

Castle Image Viewer 2.2.0 release, new documentation about KTX and DDS texture formats

Posted on

Castle Image Viewer - leaf with alpha

We have recently updated our Castle Image Viewer to version 2.2.0. Castle Image Viewer is an image viewer developed using Castle Game Engine. It supports many image formats, including common formats (PNG, JPG…) but also some exotic formats useful in game development or just general 3D visualization (KTX, DDS, RGBE). It exposes even limited image editing features, again quite tailored to our gamedev needs — it can in particular perform alpha bleeding.

Depending on your needs, you can download and use it as a standalone image viewer, or you can just consider it part of the Castle Game Engine. When you double-click an image in Castle Game Engine editor, it opens the Castle Image Viewer automatically. The viewer is bundled included in engine downloads already.

Notable improvements:

  1. New name Castle Image Viewer instead of previous castle-view-image. Consistent with Castle Model Viewer rename.

  2. Features all recent CGE improvements and new platforms, in particular it is now built also for Raspberry Pi 64-bit.

  3. We have now dedicated documentation pages about KTX (Khronos Texture Format) and DDS (DirectDraw Surface) Image Format.

Comments on the forum ➀

Android tab in editor preferences, important deserialization fix, Cocos2d rotated frames in sprite sheets, doc outlining ObjFpc and Delphi differences, creating new projects on command-line

Posted on

Viewports with cameras copied in Castle Game Engine editor
Android page in Castle Game Engine editor preferences

As we work towards releasing Castle Game Engine 7.0-alpha.3, we have a bunch of unrelated but important improvements around various engine pieces. Hopefully everyone will find in this list something to enjoy πŸ™‚

  1. Our editor has a new page in preferences to configure “Android SDK location” and “Java location”. You can configure these common settings for Android using simple GUI, instead of messing with environment variables. The change is reflected in latest Android documentation.

  2. We fixed an important issue when deserializing components into an existing owner that already has some children, possibly with conflicting names. This in particular occurs when you Duplicate (Ctrl + D) or copy-paste inter-connected component hierarchies, like a viewport with camera, in the editor. Previously, the links (e.g. assignment of Viewport.Camera) could be wrong in newly added hierarchy. Now they are always correct.

  3. We improved our support for sprite sheets in Cocos2d format. We support now rotated frames.

  4. Our command-line build tool allows now to create a new project, from the specified template. Just execute castle-engine create new-project-name, see the “create” option documentation. Inspired by Flutter tool.

  5. As we work with both FPC and Delphi, on our forum and Discord we sometimes talk about unavoidable (or maybe sometimes avoidable) differences between FPC (and FPC ObjFpc syntax) and Delphi (and FPC Delphi syntax). I collected some of my older notes — this document is not finished, nor is it complete, but I hope it is helpful: Some differences betwen FPC ObjFpc mode and Delphi (and FPC Delphi mode).

Have fun!

Comments on the forum ➀

Example talking with OpenAI (ChatGPT) assistant using Castle Game Engine (from desktop or Android)

Posted on

Castle Game Engine - Talking with OpenAI assistant

I was playing with OpenAI “assistants” lately. Assistant acts like a ChatGPT with which you can talk, but adjusted personally to you — you can instruct the assistant to answer your questions using your guidelines, possibly using a database of your uploaded files and other information. For example, I can instruct assistant to “Call the person asking the question “Gary” and add a cat joke to every answer.”. I can also upload Castle Game Engine documentation in AsciiDoctor format.

Naturally, I thought “How hard it is to actually use the OpenAI API to do this? Can I do this from Castle Game Engine application?”. Turns out it was super-trivial πŸ™‚ Took me 1.5h to have a basic version working. Later I extended it to support mobile and have better UX.

Here’s the result: https://github.com/castle-engine/castle-openai. Use this code as you please. As an example of talking with OpenAI, or just as an example of using TCastleDownload to communicate with any HTTP REST service. See the screenshot to get inspired πŸ™‚

In related news, I have merged a pull request to support custom HTTP headers and request body on Android by Vlad (phomm). This extends the capabilities of our TCastleDownload on Android — which was critical to also make this example run smoothly on Android. Thank you!

Note that I don’t provide binaries for this application. You have to follow the README — get your own API key, create your own assistant, fill their ids as shown in the README. Then compile your own version of this application. Note that using OpenAI API this way is a paid feature — you will need to put some credits, and each query will use it.

Have fun! Like it? Please support us on Patreon!

Comments on the forum ➀