Table of Contents

1. Introduction

Don’t see the feature you need? Tell us on the forum or Discord.

If you would like to see some feature implemented sooner, please support the engine development on Patreon!

2. VR and AR

VR: Michalis has access to Oculus Quest since the beginning of 2022. Port most likely using OpenXR (to include the widest possible range of devices using a single cross-platform API).

Oculus Quest 2: Developer Mode for Castle Game Engine enabled!

AR: most likely using Android / iOS built-in frameworks, as these make AR widely available on modern phones.

3. (planned for 7.0) New material components (allowing also material editing in the editor)

We want to allow you to edit materials in the CGE editor,

  • e.g. to modify (or completely override) materials from TCastleScene (like glTF),

  • to have full control over primitives (like TCastleSphere or TCastleImageTransform look),

  • to enable you to use cool CGE features like mirrors, shader effects easier.

This also means exposing new set of Pascal components to manage materials easier.

4. More Delphi platforms

See about existing Delphi compatibility. We plan to support more platforms with Delphi: Android, Linux, iOS…​

5. Load and animate glTF more efficiently

We should read meshes in a way that keeps binary layout of data in glTF, so that it is ultra-fast to load, and it is loaded almost straight from glTF to GPU.

Some modifications to CGE may be required here (CastleGeometryArrays will have to be made more flexible for this). New X3D nodes should be introduced, like BufferGeometry (same as X3DOM?).

We should also perform skinning fully on GPU, avoiding CoordinateInterpolator done on CPU.

7. More physics

  • TCastleWalkNavigation should support physics out-of-the-box.

    In progress: We have completely new navigation components in . They achieve a few things: more universal (suitable for 1st person 3D, 3rd person 3D, 2D cases), more configurable inputs, also from editor (expose new "axis" paradigm), more flexible (functionality split into a few components, easier to pick a subset of functionality you want, easier to write extensions), and honor the physics engine.

    It will take some time (to test, merge and document new approach from PR above) but eventually TCastleWalkNavigation will be deprecated. Don’t worry, the deprecated TCastleWalkNavigation will still be available for quite a while — we’re aware that many projects use it, since (as of today) we actually advise using TCastleWalkNavigation, as it’s very easy to use and flexible enough for many situations.

  • Older physics based on octrees should be phased out.

    In progress: We’re slowly already doing it. If you want to get ahead, you can already use physical colliders (see physics manual) and use queries like PhysicsRayCast instead of WorldRay.

  • TCastleSceneCore.ExposeTransforms should work both ways, to allow to attach bodies and colliders to parts of the scene. This will enable e.g. ragdolls.

  • More physics backends, not only Kraft.

    We’re looking to add another physics engine that relies on some big, well-known and open-source engine. Our current considerations are either PhysX or Bullet.

    As as result of this, more physics engines can also be added more easily in the future.

  • See more in manual about physics, subsection "TODO".

8. (IN PROGRESS) Web platform (rendering using WebGL) support

Using FPC support for the WebAssembly:

Some "glue" may also be done using pas2js. This is a nice solution to expose to our WebAssembly code the JS API we need, like WebGL. Alternatively, we could just do it in plain JS.

This is already in-progress by Trung Le (Kagamma), Andrzej Kilijański and Michalis.

I wrote a longer post about plans and status of this here: .

9. (IN PROGRESS) Particle systems

With a designer. Example usage: blood, snow, rain, fire, smoke…​ 2D, 3D.

This is already in-progress by Trung Le (Kagamma). Use cge-3d-particle-emitter or Effekseer Integration. See CGE components.

10. (IN REVIEW) Steam integration, and engine available as Steam app

Official Steam integration in CGE, see . We already used it for The Unholy Society, we want to either “just publish that approach” or propose a new, improved (without an intermediate “wrapper” library) approach.

We should also upload CGE as app to Steam.

This is already in-progress by Eugene Loza (branch: , PR: ), we also have a draft application on Steam for CGE :).

11. Release mobile castle-model-viewer (as Android and iOS application)

Associated with glTF, X3D and other formats that the castle-model-viewer (and Castle Game Engine) handles. Available in the App Store / Google Play Store. For free or for 1 USD (not sure yet; but definitely without ads, I really dislike ads).

12. Terrain features (in particular, editing terrain in CGE editor)

What we have now: The engine includes TCastleTerrain component and examples/terrain that shows how to generate terrains in various ways (from smoothed random noise, from a ready image) and render it. We also have the "Wyrd Forest" game that also uses CastleTerrain, and also includes a simple editor of terrain settings. See also news about terrains.

What we need: Visual, interactive editor for terrains, matching e.g. Unity feature set.

Enable editing heightmaps easily:

  • Edit the terrain heights within CGE editor, using something like a brush to lower/raise clicked points. To make hills, valleys in a comfortable way.

    The edited heights just land in TCastleTerrainImage with internal contents.

  • Use splatmap and enable editing it, to edit the terrain textures mixture within CGE editor. To effectively paint the terrain with different textures like grass, dirt, rock, snow.

    The splatmap is an internal (not directly visible) RGBA texture that determines the weights of the visible textures. E.g. imagine you have 4 visible texture types: grass, dirt, rock, snow. Then

    • splatmap red channel determines "how much to add grass at this point",

    • splatmap green channel determines "how much to add dirt at this point",

    • splatmap blue channel determines "how much to add rock at this point",

    • splatmap alpha channel determines "how much to add snow at this point".

    The editing code can watch over to make sure the weights are normalized, i.e. always sum to 1.0.

  • The existing terrain implementation, in TCastleTerrain and examples/terrain is a starting point — shows how we can randomize / generate a reasonable terrain with texture weights. But above additions are critical to make it really useful: in practice, for real games, people want to have control over the terrains. So the existing generation will remain part of the workflow, but only as an optional starting point.

    The fact that you can connect a few terrains together, and our generation can generate "neighbors" effectively, is super-useful and will be preserved.
  • Tools to plant big things (3D TCastleScene) in the terrain, like trees, rocks. You can do it now, though it’s manual: Use behavior TCastleStickToSurface and put multiple instances of the thing you want. Use TCastleTransformReference to make it optimal for memory when you can, so that multiple instances share the same resources.

    Optional LODs could be nice (but maybe this is outside of scope of terrains; LODs should be just on TCastleScene. Currently we have LODs on TCastleScene using TLODNode - works nice, though complicated to set up, we want to move away from exposing X3D nodes for this.)

  • Tools to plant many small things, like grass. This is a big different than "big things", and here automatic LODs that e.g. decrease density of grass with distance make sense.

  • More specialized and efficient rendering algorithm. Right now terrain in the end is just a simple big mesh of triangles. It’s actually quite fast to render (because modern GPUs can handle big shapes) but it’s not a sustainable way to render huge terrains.

  • Improve shaders for terrain to show it, like this BareGame example.

  • More than 4 layers. Each new set of 4 layers mean a new splatmap.

13. Vulkan renderer

Add a Vulkan renderer.

  • API:

    Almost all public CGE API will remain unchanged. For a long time now, we design our API to be independent from OpenGL, and all rendering (e.g. done by TCastleScene, TCastleViewport, TCastleUserInterface, TDrawableImage) is driven by a renderer-neutral API.

    Shaders will continue to be available using GLSL. There will be possibility to precompile them to SPIR-V before usage (for both Vulkan and new OpenGL, as new OpenGL also supports SPIR-V).

    Underneath, we will create a "pluggable" architecture for renderers. In theory we could implement a lot of renderers (e.g. also Metal or Direct3D) but given the limited resources, realistically we will focus on 2 renderers: Vulkan and OpenGL ("OpenGL" here meaning really a family OpenGL + OpenGLES + WebGL).

  • Approach:

    We have a simple example code that shows how you can start a new renderer: see new_renderer_skeleton example. This is great for testing initial implementation, before we have a "pluggable" architecture.

  • Header:

    I was playing with PasVulkan from which we could use a Vulkan API header. See news about PasVulkan.

    We could also get Vulkan header from GLAD 2 if only we port it to Pascal (we plan this already).

  • Platforms:

    Not all platforms support Vulkan, in particular it’s uncertain whether Apple with ever support it (they want to push Apple-specific Metal API). CGE will most likely use MoltenVK to render using Vulkan on Apple, see plans regarding macOS / iOS and OpenGL, Vulkan.

14. BGFX renderer

Look great:

  • open-source,

  • packed with features,

  • actively developed,

  • open for bindings from any language, any game engine (it is explicitly made as renderer useful for various game engines),

  • properly documented,

  • very good platform and renderer suport.

This may be even better than direct Vulkan port. We shall see. On one hand, this provides more possibilities than just Vulkan (e.g. direct Metal renderer). And it may be easier to use than Vulkan. OTOH, it will not allow to squeeze "every last bit of performance from Vulkan" (though we really don’t need that in CGE in the first place; there are lots of optimizations on the table in CGE before it’s worth even thinking about low-level Vulkan optimizations).

15. (IN REVIEW) Distance field fonts

See about Distance field fonts. See code from Chris Rorden showing how to do it in Lazarus.

16. Mobile

16.1. Wireframe on OpenGLES

Since glPolygonMode is not available at all on OpenGLES, we need to be able to generate wireframe geometry arrays on CPU, adding a "wireframe" option to CastleArraysGenerator that will generate a different (line) primitive for TGeometryArrays. Then the renderer can use such TGeometryArrays for OpenGLES.

This is started now, by having Shape.shading = "WIREFRAME" option, see Shape.shading field. We need to

  • make it available for all geometry shapes

  • make this feature more flexible, so that the renderer can switch between wireframe/non-wireframe rendering without any cost.

  • And then we can implement Attribute.WireframeEffect on OpenGLES correctly,

  • and allow to set Wireframe on specific viewports (so that some viewports may view wireframe, independent of others) on OpenGLES.

16.2. On-screen keyboard on iOS (done on Android)

16.3. TGLImage.GetContents on OpenGLES

TGLImage.GetContents is not available on OpenGLES, as it doesn’t support glGetTexImage. Fixing it is a matter of implementing alternative way that draws texture to FBO and grabs using SaveScreenGL (using glReadPixels internally).

One has to use TGLRenderToTexture to render quad with a texture (making sure the framebuffer size, quad size, and texture size match, and without filtering) and then use glReadPixels to get the pixels from FBO. This will work on mobile (and also on desktops, although it will be less optimal alternative to glGetTexImage).

17. macOS: Package engine as one big application bundle

This will:

  • be simpler to users, as the engine will be "one single application" for macOS users.

  • avoid troubles resulting from Apple translocation. It right now prevents the CGE editor from detecting CGE path.

  • avoid current duplication of castle-editor/data in distributed package, thus making it smaller by ~60 MB.

See macOS.

18. macOS: Have signed app bundle for the editor

This will allow to run CGE editor on macOS by just double-clicking it, out-of-the-box.

See macOS.

We should also enable developers to easily sign their own applications packaged with CGE build tool.

19. (IN PROGRESS) fps_game should be redesigned using editor, CreatureCreatures / CastleResources / CastleLevels / CastleItems / CastlePlayer should be replaced with a better API

In progress. See news post. On branch fps-game-upgrade.

These 5 units (CreatureCreatures / CastleResources / CastleLevels / CastleItems / CastlePlayer) expose a high-level API, that sits on top on existing classes (like TCastleScene and TCastleTransform). But I am not 100% happy with their API. Reasons:

  • The API is too specialized at some points (3D games with creatures / items pickable),

  • It is confusing how it maps to API underneath (e.g. TPlayer somewhat controls the TCastleNavigation).

Gradually I will want to express their features in different ways, in ways that are more closely and obviously connected with TCastleScene / TCastleViewport / TCastleNavigation. Basically, I’m very happy with current API of TCastleScene and TCastleTransform, and I want to make it more obvious how it is related to creatures/placeholders and other concepts introduced in CastleLevels and CastleCreatures and CastkeResources. Currently they use TCastleScene and TCastleTransform inside, but the relationship is non-obvious.

It’s not going to happen any time soon, but it will happen gradually, over the course of next 1 or more years. That is, some of the features of the 5 units mentioned above will become available in other ways too (more flexible, and more obviously connected to TCastleScene).

I know this sounds vague, because I have not yet clarified these plans in my head:) These 5 units are useful, they provide various features on top of TCastleScene. I’m not going to just "ditch" them or even deprecate them, before I made a better API that also has these features. For example:

  • New TCastleScene.Load should be able to take a callback (or some class instance) to easily perform the "placeholders" functionality of TLevel.Load in a flexible manner (user can decide what to replace with what).

  • There will be TCastleSceneView that provides part of the functionality of T3DResource (multiple TCastleSceneView share a single TCastleScene but can show different animation frame of it), but without some often-unnecessary "baggage" from T3DResource (like refcounting of T3DResource, and it’s special Prepare/Release methods).

  • It should be possible to add an A.I. (like TWalkAttackLogic) to any TCastleTransform instance.

I know I want to go in this direction. Based on the questions (including on Discord) I see that the API of these 5 units is not clear to people. It wraps TCastleScene / TCastleViewport / TCastleNavigation, but in ways that are not obvious, and that is something I want to improve.

Again, bear in mind that it will not happen any time soon :) You can safely and happily use these units, probably for a few years to come.

But it is something I think about for the future, and it may explain some of my decisions. E.g. that is why I don’t plan special integration of TCastleCreature with castle-editor. Instead I want to enable you to add future TWalkAttackLogic to any TCastleTransform one day. And thus we will have "easy creatures" in CGE but with more flexible API.

20. Bridge TDrawableImage with TCastleScene, enable drawing UI into TCastleScene, to have UI rotated in 3D with perspective.

21. MDL and/or MaterialX integration

We can make 3D modeling of realistically-looking stuff much easier by reusing libraries of realistic materials.

22. USD – Universal Scene Description support

Explore possibility to support USD – Universal Scene Description format as a first-class citizen, alongside glTF and X3D, in CGE.

23. Integration with Nakama (scalable server for social and real-time games and apps)

Integration with Nakama:

Nakama is an open-source server and client library/API that provide networking capabilities typically needed in games.

  • The server is written in Go (see source code) and can be extended using Lua, JS, or Go modules. See server framework.

  • It supports out-of-the-box stuff like user accounts, matchmaking (connect people into rooms where the game happens), leaderboards, chat, etc. There’s infrastructure to synchronize data between players in a multi-player game.

  • Client library can be used from various game engines and languages so we’re confident it can be used from CGE too.

  • You can host the server yourself or pay to get ready hosting.

  • As you can see in above links, it seems really well documented, and actively maintained. These are naturally critical qualities for our dependencies.

I think Nakama may give CGE networking capabilities comparable with some popular solutions known from other game engines :)

Allowing to trivially get multi-player functionality in your games.

24. Project settings editable using GUI

We will expose both current CastleEngineManifest.xml and data/CastleSettings.xml as something you can edit yourself with GUI.

But we don’t want to create and maintain a custom GUI for them, instead the plan is to:

  • Create Pascal components with published properties representing their data.

  • Make the project settings files just "JSON design files" for the editor.

So you’ll have a file like project.castle-project and using editor menu item like "Project Build Settings" will really just open a design project.castle-project (JSON) in the editor, and it will be just a serialized TCastleProject component. Same for "Project Runtime Settings" which edits data/settings.castle-project-settings.

Bonus: we’ll associate *.castle-project with the system, to open when you double-click it e.g. from Windows installer.

Bonus: you can add non-visual components to data/settings.castle-project-settings and load them using Container.DesignedComponent('xxx'). This is great e.g. to add sounds or fonts or other data that you want to later load in CGE, from any view.

There are a few details that have to be ironed out here:

  • how should the new equivalent of CastleEngineManifest.xml and data/CastleSettings.xml interact. We will likely keep 2 files, project.castle-project and data/settings.castle-project-settings, as

    • Some information doesn’t need to be packed into data, part of it could even be considered "somewhat secret" (e.g. SDK IDs for Android analytics should not be present anywhere in the non-Android builds).

    • Some information should be packed into data automatically, by default, everything. To enable that Bonus: you can add non-visual components feature.

  • most intuitive names for all the things above (menu item names, component names, extensions etc.) :)

25. Creating animations in CGE editor, for UI and transforms

Allow designing and testing animations in CGE editor.

The features cover animating typical UI/transform things that you see in CGE editor directly: e.g. UI stuff (like TCastleUserIterface.Translation, TCastleImageControl.Color), 3D stuff (TCastleTransform.Translation, TCastleTransform.Rotation etc.).

Animating everything in CGE is already possible right now using code. You can update any values you want in Update method of your view and change any value you need (like MyControl.Translation) using routines like Lerp or SmoothStep.

The point of this feature is to allow to design and see simple animations from editor. Code will then be able to just play them (e.g. using simple method MyAnimation.Play) whenever needed.


  • Make it possible to animate (at least!) any property of TCastleUserInterface and TCastleTransform. Access the property using RTTI, and at design-time in editor allow to choose TargetObject and TargetProperty with suitable type.

    Bonus: allow to animate any property of any TComponent.

  • It should allow to animate at least any Single/Double, TVector2/3/4 properties (this includes also colors, as TCastleColor[RGB] is just alias for TVector3/4; this includes also rotations, that is just TVector4 but can use slerp for interpolation).

    Bonus: allow to animate other property types. E.g. animating discrete (like boolean) actually makes sense — to hide stuff by animation, by changing Exists at specific point in time.

  • It should use TCastleBehaviorBase that will allow to attach it to any TCastleUserInterface and TCastleTransform. See talk about it in .

  • Each such animation should define:

  • Bonus: Group animations, so that from code you can fire like MyUserInterfaceAppear.Play and it runs a number of animations at once — e.g. something "slides in" (translation changes), something appears (Exists changes), something fades in (Color.alpha changes)

See also:

26. Screen effects - expose as nicer components

Address a few shortcomings of our (see examples/screen_effects_demo/, screen effects):

  • Change terminology. "Screen effect" is non-standard, "post-processing effects" are better.

  • Expose as components some standard effects, like blur, changing colors in HSV, grayscale. They should have easy Pascal properties, serializable to JSON, and wrap the related X3D nodes underneath.

  • Expose as component a customizable shader effect allowing you to provide GLSL code in a text box (TStringList editor) in CGE editor.

  • This depends on making a more generic TCastleComponentList to expose TCastleScreenEffects.ScreenEffects list nicely.

27. Export any TCastleTransform hierarchy to X3D

Currently you can only export TCastleScene to X3D.

28. Export TCastleScene, or any TCastleTransform hierarchy, to glTF

Currently you can export TCastleScene to X3D or STL.

29. Allow animating selected node graph properties, without changing the graph, to be able to reuse graphs

Right now our X3D graph usage is similar to HTML DOM usage from typical web applications: we modify the graph at runtime, everything that changes stuff (like animations) just changes the graph. This is simple to use, it nicely allows to animate everything in X3D and gives developers an easy way to modify everything at runtime.

The downside is that we waste significant memory, and loading time, in some cases. If you want to play different animations on each TCastleScene, then they need to have a different graph even though they are loaded from the same URL. Hence using e.g. TCastleScene.Clone or TCastleSceneCore.Cache really internally makes multiple copies of the graph. This could be more optimal in the future. E.g. assuming your model only uses glTF skinned animation or animates simple transformation position/rotation/scale, we could make the graph read-only, and only maintain small "diff" information at each instance.

30. FMOD Studio support

Right now our FMOD backend uses only "FMOD Core API".

We want to enable using higher-level FMOD events that drive the sound banks exported from "FMOD Studio".

31. Wwise backend

Allow using AudioKinetic’s Wwise as sound backend, and as a middleware to design sounds.

32. Asynchronous loading of assets

As described in threads, we want to allow loading assets asynchronously. This means that you use CGE API from one thread, but some operations are not "blocking" and CGE can internally use threads to finish their work, while your code continues to calculate, CGE events like Update continue to be processed etc.

For example:

TCastleScene.LoadAsync(const Url: String; const OnFinish: TNotifyEvent);


TCastleTerrain.UpdateDataAsync(const NewData: TCastleTerrainData; const OnFinish: TNotifyEvent);

We already use such approach e.g. with TCastleDownload. Internally it can download in a thread, but you don’t need to worry about inherent "hard" issues with threads (synchronizing communication between threads, being careful who/when touches the shared variables). This approach results in:

  • Really comfortable API. You handle everything from one thread, you get simple callbacks when things are done, you can simply watch (e.g. in some Update) status of something, display progress bars, interrupt the operation etc.

  • Flexible implementation underneath. It can use Pascal threads underneath, or it can delegate work to another asynchronous API (e.g. to download using Java classes on Android), it can even fallback to synchronous if threads are not possible on some platform.

And it is possible to load OpenGL things in a thread: by having separate OpenGL context for the background thread, that shares resources (like VBO).

The ultimate demo is to implement exploring a huge city and loading neighboring pieces of the city asynchronously.

I mentioned this in the bottom part of Slides, movies and thoughts from my GIC 2022 presentation .

33. Merge TCastleImagePersistent and TDrawableImage

One less image class (we have too many image classes, see ).

And it will avoid current counterintuive fact:

ImageControl.DrawableImage.CustomShader := Xxx;

The above is ignored, because ImageControl.CustomShader (equal to ImageControl.Content.CustomShader) overrides TDrawableImage.CustomShader. Similarly a few other drawable image properties, as TCastleImagePersistent.Draw does now:

{ All the DrawableImage properties must be set here,
  in case muliple TCastleImagePersistent refer to the same
  DrawableImage instance through the cache.
  Fortunately, almost all TDrawableImage properties have zero cost
  of change. }
DrawableImage.SmoothScaling := FSmoothScaling;
DrawableImage.Clip := FClip;
DrawableImage.ClipLine := FClipLine;
DrawableImage.Rotation := FRotation;
DrawableImage.RotationCenter := FRotationCenter;
DrawableImage.Alpha := FAlphaChannel;
DrawableImage.Color := FColor;
DrawableImage.CustomShader := FCustomShader;

34. (IN PROGRESS) Gamepads (joysticks) support

Goal: Support modern gamepads (joysticks) with a nice API.

Note: We have support for gamepads (joysticks) already, see CastleJoysticks and examples/joysticks/ . But it is not easy to use — I’d like to improve the API, and improve it to handle various gamepad types in a more "seamless" fashion.


  • It should support at least the most popular controller, which X-box compatible controller, out-of-the-box.

    It seems we can easily support much more, using joysticks database: . But I make it explicit: the critical feature is support for the most common X-box compatible controller. Support for, potentially, every gamepad that exists in the world is secondary :)

  • Should support at least Windows, Linux, and Nintendo Switch. Switch support in this case is justified — because we already support Switch gamepads, but we’ll want to upgrade it to new API.

    Of course support for more platforms is desired. macOS, and maybe even mobile (it does seem one can connect gamepad to Android through at least Bluetooth, it actually works). But these are secondary. The platforms mentioned above are primary for this feature.

  • Should support multiple gamepads.

  • API should be nice. Current CastleJoysticks is complicated. This means:

    • TInputPressRelease structure, as send to TCastleUserInterface.Press (so in particular, TCastleView.Press) should have a type like GamePadButton (alternative to key on keyboard, or mouse botton) that occurs when user presses / releases the button. It should say which gamepad was used to press it (to support multiple joysticks connected to system). And it should report a button.

      Buttons should have agnostic names, like North, East etc. Avoid using names like ABXY that are in different places on different gamepad models (Xbox, PS, Nintendo…​). Maybe we can also have names like Accept, Cancel to follow conventions (e.g. on Xbox controller, A corresponds to "Accept" by convention, B corresponds to "Cancel").

    • TCastleInputAxis (that is also already in progress) should allow to observe chosen gamepad axis (based on gamepad index, and choice horizontal/vertical, also choice of gamepad axis — typical gamepads now have 2 axis). This is already a nice API to observe input that we want to have.

35. Smart Tasks

Allow to define tasks that should occur regularly, but do not have to be done every frame. The engine should then automatically execute the tasks based on their need and current workload.

E.g. animation task may say "I want to update the model every frame, but actually I don’t have to — if under heavy workload it’s enough to only update 30 times per second or such". This would be a better (more general, smarter — activated automatically) way of optimizing it than current TCastleScene.AnimationSkipTicks.


The API (terminology) and implementation have to play nicely with Delphi existing concept of "tasks" from Delphi Parallel Programming Library. Delphi already has a "task" meaning "a unit of work that can be executed in auto-created thread (using pool of threads underneath)", see


  1. Our tasks, that are mainly to execute tasks in the main thread but with some delay ("execute this when convenient, I don’t need it done right now") should be clearly something different. To avoid confusing API for people that know Delphi tasks.

  2. When using threads, then we should use Delphi tasks (on Delphi), where possible. Only for FPC we’ll need to duplicate subset of it (unless FPC will get the compatible implementation).

36. Improve automatic reloading of files (in editor) when they changed

Automatic reloading (CastleInternalFileMonitor) now:

  • Doesn’t capture changes to secondary files, e.g. to textures used in glTF file. We only watch the file indicated by TCastleScene.Url now.

  • When TCastleScene.Cache, the file will not be reloaded from disk correctly.

  • Not all components implement necessary watching logic. For now only TCastleSceneCore. All components should eventually do it, e.g. TCastleTiledMap, TCastleImageTransform, TCastleImageControl.

37. KTX 2.0 support

A great format, by Khronos. Enables managing compressed textures much better. (than our existing solution: )

38. Expose component name for Pascal code

Right now to access a component set up in the design, you have to manually add it to the published section of the design, addign a declaration like MyViewport: TCastleViewport.

The goal is to make it more automated. A bit like Lazarus or Delphi IDE when exposing components to code — but with some twist.

It would be easy to just expose all named components from the design in the published section of the view (this would be experience quite like when Delphi/Lazarus do) but, since typical game designs (we’ve seen it in Unity games in CAG) can contain thousands of components easily, and most of them are not supposed to be accessed from code, we want to go one step further:

  • Add a button "Expose To Code" (available on single component, or selection of components).

  • Once used, the component will be added to the published section of the view (name: type), and will be updated there (on rename/delete of this component, or change of it’s class).

  • This is also means we’ll edit the uses clause of unit to make sure all used component classes are registered, and declared, so that declarations in published section work. This is also something Delphi/Lazarus do. We know the unit of each component, so it should be easy.

It is possible we’ll add markers {$region 'Castle …​'} to help organize this. See the current markers in gameinitialize.pas.

39. Allow to override design properties when instantiated using TCastleDesign, TCastleTransformDesign

Allow to customize the hierachy instantiated through TCastleDesign or TCastleTransformDesign.

In Unity, this is called "prefab overrides". In Delphi/Lazarus, frames also offer this functionality.

The idea is that, in the "outer" design, we can save only the differences from your original design to the customized version.

See Custom components documentation, and the section "Using designs to visually set up default state of your component".

40. Make shadow maps available by a trivial property on light sources

Right now, activating shadow maps is more involved. You need to setup special X3D nodes, and they only work within a single scene.

This is in contrast to shadow volumes that are trivial to activate: you literally just toggle one checkbox Shadows on our light components (TCastleXxxLight).

We want to have both these shadow approaches be trivial to enable. Light source should just have a property like ShadowsMethod to choose shadows algorithm..

Alternative, rejected, API idea was to turn Shadows into an enum with a possible "none" value, like Shadows: (None, Volumes, Maps). Separate Boolean to choose whether shadows are enabled at all, separate from choosing shadows algorithm, seems more natural.

41. Component list class, to easily expose serialized list of components in editor

We want to have a component list class, that

  • Maps to a subtree in the "Hierarchy" in CGE editor,

  • Can be used to express current (this will make some code in editor and CastleInternalInspector simpler):

    • TCastleTransform children of TCastleTransform,

    • TCastleBehavior children of TCastleTransform,

    • TCastleUserInterface children of TCastleUserInterface

  • Can be used to express future things:

  • Is generic, so we can be safe at compile-time about what is allowed to be inserted. That’s why we don’t want to just use standard TComponentList.

  • Would allow CGE editor to easily hide some lists, while not hiding others. E.g. whether to expand TCastleBehavior in the hierarchy — can be just UI choice.

    Conceptually, when Unity has hierarchy (of GameObject) on left and list of components (components in Unity sense, i.e. pieces of GameObject) on right, we instead have a tree of components (components in Pascal and CGE sense, i.e. TComponent). It is just editor UI decision — which levels are shown in the tree (hierarchy), which are not (e.g. behaviors could be hidden, or shown in some different way, in editor — and it shall be unrelated to the Pascal classes organzation).


TCastleBaseComponentList = class(TComponent)

  • Internally uses TComponentList for storage because we want items to auto-disappear when they are freed wherever.

  • Do not inherit from TComponentList, to not expose everything, limit access to our methods/properties. So only use it as a private field.

  • Non-generic, editor can use it as a base class for all nested lists.

  • Editor operations like move up/down, remove, add, should use this class.

TCastleComponent.GetComponentLists method: Query all TCastleBaseComponentList. Maybe it should just use RTTI to query all TCastleComponentList<T> on given object, from them extract TCastleBaseComponentList and return them. This is crucial for editor to show hierarchy. One of the lists should be "default" to show it without intermediate item in hierarchy (e.g. TCastleTransform children are Children: TCastleComponentList<TCastleTransform> but we don’t display Children intermediate item in hierarchy).

TCastleComponentList<T> = class(TComponent)

  • Generic, safe to use from code.

  • internally uses InternalBaseList: TCastleBaseComponentList to store items, as private filed. (Do not inherit, to not expose everything non-generic.)

Another phrasing of this (equivalent, mostly):

Unify the processing of both visual children of TCastleTransform, and visual children of TCastleUserInterface, and NonVisualComponents — by new TCastleComponentList<T>. This will be backward compatible, and will guarantee that all these iterations really use the same mechanism (right now these iterations are ~consistent just because they have been manually made to look siimlar each time).

So we’ll have

TCastleComponent = class(TComponent)
  NonVisualComponents: TCastleComponentList<TCastleComponent>;

TCastleUserInterface = class(TCastleComponent)
  Children: TCastleComponentList<TCastleUserInterface>;

TCastleTransform =  = class(TCastleComponent)
  Children: TCastleComponentList<TCastleTransform>;
  Behaviors: TCastleComponentList<TCastleBehavior>;

and iterating with for .. in …​ ` will be always equivalent to iterating over `Children.


for C in MyTransform do

will be equivalent to

for C in MyTransform.Children do


for C in MyUserInterface do

will be equivalent to

for C in MyUserInterface.Children do

And you can also do

for C in MyTransform.Behaviors do…​

for C in MyTransform.NonVisualComponents do…​

Right now…​ it’s already mostly like that, but due to the fact that I declared a few things manually in the same way. The new TCastleComponentList<T> should force it to be consistent, and also make some code easier for editor.

42. New API for Tiled layers

  • New class TCastleTiledMap.TLayer = class(TCastleComponent)

    TODO: Make sure it can be serialized OK. Fallback on TCastleTiledMapLayer if necessary. But we prefer TCastleTiledMap.TLayer.

  • New published property Layers:TCastleComponentList<TLayer> inside TCastleTiledMap.

    Depends on TCastleComponentList plans. We want to serialize the properties of layers this way.

  • Remove existing Layers set from TCastleTiledMap.

    Write code in TCastleTiledMap.CustomSerialization(const SerializationProcess: TSerializationProcess); to upgrade existing designs to new API.

    Pascal code using old Layers will just be broken and have to be upgraded, acceptable.

  • Exists should be in TCastleTiledMap.TLayer, and not in TCastleTiledMapData.TLayer.

    Should toggling it toggle also TCastleTiledMapData.TLayer.Visible? Or let TCastleTiledMapData.TLayer.Visible stay as "initial value"? Undecided, not really very important.

  • The long-term goal is to have nice components for layers and maybe more (tiles), inside TCastleTiledMap, with published properties, that can be designed in CGE editor, and that are serialized using existing system to JSON.

    It should be possible to design layers (and maybe more, like tiles) in CGE editor.

    This way we can go, step by step, to having own Tiled-like editor in CGE, like Godot or Unity.

    At the same time, we want to support Tiled (as external application for map editing) and support it fully, because Tiled is great! and it may take us long time to actually have fully useful tile editor in CGE editor. The road should be that Data stuff, and everything in TCastleTiledMapData, becomes less and less useful. It’s an internal detail whether our public TCastleTiledMap.TLayer has a reference like Data:TCastleTiledMapData.TLayer or not.

43. Built-in tile editor in CGE, with support for 3D models on a grid

Built-in Tiled-like editing features in CGE would be great.

This is admittedly a long-term goal. A whole system for this, esp. with 3D, would be cool but also a significant new work.

What will likely be done sooner: "snapping" for 3D operations, that fils some subset of this functionality, e.g. allows to put 3D buildings on a grid.

44. ExposeTransforms is a powerful idea that can cover more use-cases

See docs and TCastleSceneCore.ExposeTransforms. It already contains TODOs showing how it should work like.

Moreover fix problem with names:

  • cannot duplicate model with ExposeTransforms now

  • cannot add another model with same bone names, before customizing bone name prefixes

  • solution: remove ExposeTransformsPrefix, rather add new property BoneName that doesn’t have to be unique and can be used for synchronization

  • document this on docs

Moreover, maybe:

  • ? Should expose the parent bones too (otherwise editing from code is hard, and applying edits back is hard — as you see a combined transformation only)

  • ? Rename to just Expose? ExposeTransforms sounds convoluted.

45. Improve editing (TCastleEdit, planned TCastleMemo)

  • Moving cursor freely in text (clicking, arrow keys, ctrl+arrow keys to move by words)

  • Free selection of any text subset (clicking, shift+arrows)

  • Multiline display (thus TCastleMemo, which should internally share code and be essentially TCastleEdit with > 1 line)

  • Right click with contextual menu - copy, paste, cut, select all, use platform-specific input method

  • Manual focus. Clicking on edit should keep it focused, no matter where the mouse moves. Tab or clicking elsewhere switches focus. Right now you can workaround it / do it manually by setting Container.ForceCaptureInput to the edit control.

All above will have to be synchronized with on-screen keyboard behavior on Android.

Moreover we want to support on-screen keyboard behavior on iOS as well, see .

46. Editor Dark mode

Dark Mode design by Adrianna Matejek

I can’t count how many times I’ve been asked "when is the Dark Mode coming to CGE editor" :)

  1. One answer: It is already possible and easy on non-Windows.

    We use LCL and our editor just follows your OS (Windows, GTK, …​) theme. If you switch your system theme to something dark, then all your applications (including CGE) will become dark. This already works great e.g. on Linux or FreeBSD with GNOME, just switch your theme using GNOME settings and enjoy dark mode for everything.

    Unfortunately, on Windows, there’s no setting to change the WinAPI controls to use the dark theme.

  2. On Windows you can use MetaDarkStyle Lazarus package.

    We have a PR with this, not merged yet. You can easily do this yourself:

  3. Big Plan: The ultimate solution, that will allow to switch dark mode on/off on all platforms with exactly the same results, will come from reimplementing CGE editor using CGE user interface components. We made a decision some time ago, and it will definitely happen — but it’s still a big task, and it will take some time. The major benefits of it will be:

    • We will be able to use the editor on all platforms there are CGE targets. In particular, on the upcoming web target, which means you will be able to create and edit your games in your browser! Or even on mobile (but don’t hold your breath for making games on mobile — the form factors of mobile devices will likely make UX of CGE editor on mobile not very good).

    • It will necessitate CGE UI improvements, from which all CGE applications will benefit. For example, ready tree view, object inspector and list components.

    • It will allow to turn our "inspector at run-time" into full-featured "editor at run-time".

    • It will allow to avoid some LCL limitations, sometimes widgetset-specific. E.g. LCL GTK 2 widgetset uses deprecated GTK 2 and has known crashing issues, Qt5 widgetset needs libqt5pas library that most people don’t have (or don’t have in relevant version for latest LCL), macOS widgetset does not have a functional frames list and thus sprite sheet editor sucks…​ We will be able to ignore all of this, as they will be replaced by a cross-platform implementation.

    • And, last but not least: the dark mode, on all platforms, will be trivial to implement :)

To improve this documentation just edit this page and create a pull request to cge-www repository.