Visual Studio Code integration, intelligent code completion with our LSP server, also for Emacs, NeoVim and other text editors

Posted on

Visual Studio Code - Pascal code completion
Visual Studio Code - Pascal LSP server configuration
Visual Studio Code - Installing VSIX

If you use Visual Studio Code, we have a new manual page for you and an LSP server distributed and tested with Castle Game Engine that provides a perfect Pascal code completion.

Most important link

Read everything here: Visual Studio Code with Castle Game Engine.

What is an “LSP server”

LSP (Language Server Protocol) is a protocol to define code tools functionality (e.g. code completion) in a way independent from the text editor.

  • Multiple text editors can act as LSP clients, e.g. VS Code (where the LSP originated), Emacs, Neovim.

  • They can access any LSP server. There are lots of LSP servers, in particular there are a few suitable for Pascal.

What I did

I was having some fun exploring the options and I actually got to work 2 LSP servers targeting Pascal: Philip Zander (Isopod) LSP server and Ryan Joseph (genericptr) LSP server. They both use Lazarus CodeTools underneath.

I then modified them (both) adding some CGE-specific features and testing how to make them perfect. I wanted to have it all — support for VS Code (which I know many people like), Emacs (which is my favorite text editor), out-of-the-box support to complete code using CGE API, working everywhere (I tested both Linux and Windows).

  1. We had a few conversations with Philip Zander (thank you a lot for all the information how everything works and being open to my PRs!), I made our fork with Castle Game Engine enhancements, I submitted some PRs back: #1, #2, #4.

  2. I also made a fork of LSP server from Ryan Joseph and submitted PR #33.

My forks add support for additional configuration using INI file and you can make LSP servers trivially aware of CGE paths this way. The details of my additions are in README files on both LSP servers.

Note: Both the above LSP servers actually come from initial Arjan Adriaanse work (though, after 3 commits, it seems he didn’t maintain it further) on github.com/arjanadriaanse/pascal-language-server.

Finally, I gathered a lot of notes and links about existing options to use LSP with Pascal.

Making it easy to use

As a last step, I made the setup as easy as possible to use:

This was a lot of integration work πŸ™‚ And it’s not finished! A lot of pieces can be improved and/or it can be made to work more out-of-the-box. It is possible we’ll have our own Castle Game Engine extension for VS Code one day. It could take care of LSP, help with debugging and running CGE projects from VS Code, maybe more?

Stay tuned πŸ™‚ Do you like this? Please support our work.

Comments on the forum (4) ➀

TCastleTransform.RenderLayer to render stuff in front, TCastleScene.PreciseColisions, upcoming plans

Posted on

So I have now around 5 things in parallel in progress πŸ™‚

  1. Review and merging of new physics (components for colliders, rigid body, joints) with Andrzej KilijaΕ„ski. It takes a while, but it’s also a large change, and I want to iron out various API details.

  2. Working on big upgrade to FPS game graphics with Adrianna Matejek and Alya Vaneskehyan. Aside from a prettier demo, I get from them a ton of feedback about engine experience from a perspective of experienced 2D and 3D graphic artists. And I have a ton of resulting good TODOs and priorities that will over time find their way into the egnine (some of them already did).

  3. I’m planning restructure of our settings. I would like to deprecate our CastleSettings.xml in favor of a design like CastleProject.json that allows to specify more, and is editable in editor too. In addition to current settings, it would also allow to define some project-wide components (like sounds and fonts that should be loaded and available for the entire application lifetime).

    While a plan is written down, I will likely postpone it after 7.0 release.

  4. I have a great plan how to allow to visually customize materials and material effects in CGE. We have some unique challenges and unique features (our compositing shaders or easy mirrors are really great, we just need to expose them in a way that is simple — both from editor and from Pascal to use).

    I consider this high priority and want to push to make it happen before 7.0 release.

  5. I’m organizing a Windows certificate so that our EXE files are less scary to run on Windows πŸ™‚

Some things done lately that are already available in CGE master branch:

  1. New property TCastleTransform.RenderLayer to force some things to be rendered in front of others. Particularly useful in 3D, e.g. to display weapon in FPS game always in front of other 3D objects.

  2. New property PreciseCollisions and deprecating previous complicated Spatial property. This is anyway part of old “simple physics” — while still available, with time we will want to move everything to new physics, so PreciseCollisions is doomed to be deprecated (at some future point, after 7.0 release) too. But for now it’s great to e.g. easily control how FPS navigation by TCastleWalkNavigation behaves.

  3. Important fix for DistanceCulling with shadows.

  4. Testing LSP servers with Pascal! More about it in next news post πŸ™‚

Comments on the forum ➀

New editor features: change class of any component, shortcuts to tools, multi-selection of transforms

Posted on

Multiple selection of lights

We continue to improve the editor to make it easier to design large 3D and 2D games.

  1. Context menu of each component (available if you click with right mouse button on a component in the hierarchy panel, on the left) contains now a menu “Change Class…”. This allows to change:

    • any TCastleUserInterface class to another TCastleUserInterface class (for example change empty group to a color rectangle),
    • any TCastleTransform class to another (for example change light type between point / spot / directional),
    • any TCastleBehavior class to another (for example, change collider between sphere / box / mesh etc. in the upcoming physics work),
    • any non-visual class to another (for example, change font class to a family of fonts with different bold / italic etc. versions).
  2. You can now select multiple TCastleTransform instances by clicking on them with Ctrl key held down in the design (middle) panel (which shows 3D view in case of 3D viewports).

    Multiple selected transformations are also better shown now.

    This is great to select e.g. a number of light sources or scenes and change their properties (e.g. intensity or color of the lights).

    Note: For now, you cannot transform (move/rotate/scale) a multi-selection using a gizmo. But we have made now a first step to enable this too in the future:)

  3. You can now add TCastleBehavior from right-click menu when another TCastleBehavior is selected. Esp. useful when adding collider alongside rigid body — this is great for upcoming physics.

  4. Use Alt+1, Alt+2 etc. key shortcuts to quickly switch between interact / select / move / rotate / scale tools.

  5. Use Escape key shortcut to reliably focus the design (middle) panel. This is great if you want to use e.g. F (focus) or 1 / 3 / 7 key shortcuts. In case you stand on an edit box, the Escape key will reliably switch focus to the design.

Comments on the forum ➀

Faster compilation with cache

Posted on

Compilation cache effect

You can speed up the compilation of all future projects if you initialize “compilation cache”. Underneath, it means we will just compile all CGE units to a special “cache” directory (stored inside user directory, independent from the current project) and we start compilation of each project by taking all CGE precompiled units from this cache.

The effect: your compilation can be lighting fast. In my tests, if the cache is initialized,

  • It takes 2.5 seconds to build a Linux application.
  • It takes 10 seconds to build an Android APK.

And these are times of the first build, on a newly created project.

How to initialize cache?

In CGE editor, use the menu command “Run -> Cache (Precompile Engine For Current Platform)”. By default it will cache compilation for current platform (e.g. Linux or Windows where you run the editor). Switch the platform using “Run -> Platform (To Build And Run) -> …” menu item, and redo the “Run -> Cache (Precompile Engine For Current Platform)” for each platform.

Note: The menu commands to initialize the cache are only available when you have some project, any project, open. This is just a consequence of our current UI (we already have output console, and platform choice, when the project is open). But the created cache is actually independent from the project.

Or you can do it using the command-line CGE build tool, if you prefer (and your compiler, like FPC, is available on PATH environment variable). Just execute something like this:

castle-engine cache # cache for current platform
castle-engine cache --target=android # add cache for Android, both 32-bit and 64-bit

Why like this?

Right now: Without the cache if you compile the project for the first time, we actually always compile the engine too. Moreover (with or without the cache) all the compilation output (like .o, .ppu files) is stored in project-specific castle-engine-output.

Why?

  • This makes things simple. It means that we just provide to the compilers your main source code (program or library) and the paths to all sources (of your project, and of the engine). And the compiler (FPC or Delphi) just does whatever is necessary.

  • It means that switching compilers, FPC versions etc. is not an issue. Again, the compiler will just do what it should. E.g. the compiler should realize that standard units have changed compared to previous compilation.

  • It is friendly to engine developers πŸ™‚ Changing the engine unit has the same effect as changing your project source code. In both cases, the compiler just figures out the minimal set of units to recompile.

  • The debug/release modes change not only the compilation options of your application, but also of CGE units. This is helpful e.g. to activate certain additional assertions and range checks in the engine.

  • It allows you to set, within each project, some defines that affect engine compilation. For example you can change CastleWindow backend by using appropriate define. In general we want to make this use-case not important (it would be e.g. cleaner to switch CastleWindow backend by using a particular unit, it would also make it better for cache) but it is still practically useful for now.

We have designed the cache mechanism to not interfere with these advantages:

  1. The current cache contents (.o, .ppu files) are copied over but without overwriting the current .o, .ppu files in the project. So the precompiled units from cache are a starting point to your project’s compilation directory. But the precompiled units do not overwrite the existing ones, moreover the compiler will overwrite them (in the project) if e.g. you have changed CGE since making the cache. So the cache tries hard not to conflict with what you’re doing.

  2. There is a separate cache for each mode (debug,release,valgrind).

Comments on the forum ➀

Wireframe view in editor, camera improvements: navigation under any transformation, zoom in Walk mode

Posted on

Wireframe + Polygons view
Wireframe view
Regular (Polygons) view of new castle demo
  1. Use Viewport -> Wireframe mode menu, or just hit Alt+Z shortcut, to toggle between viewing:

    • Polygons,
    • Wireframe or
    • Polygons + Wireframe (internally known as weSolidWireframe).
  2. At design-time, in “Fly” mode, mouse scroll wheel now does zoom (if you don’t have right mouse button pressed; when right mouse button is pressed, it changes moving speed, as before).

    More details:

    Zoom (by mouse scroll wheel) is now available for all navigation modes, including TCastleWalkNavigation. Although it is disabled on TCastleWalkNavigation by default, but you can just enable it by MyWalkNavigation.ZoomEnabled := true (or clicking on ZoomEnabled checkbox in editor).

    Editor and view3dscene enable this zoom by default.

    Also, zoom-in now honors collision detection. Though at design-time we disable collision detection.

  3. We’ve done a few fixes to make TCastleWalkNavigation navigation, including mouse look, work even when the camera is a child of some other TCastleTransform with some transformation.

    This gives you more flexibility where do you place TCastleCamera in the transformation hierarchy.

Comments on the forum ➀

Concept art teaser: Huge graphical (and functional) upgrade to our FPS game is coming

Posted on

Concept art by Adrianna Matejek for new FPS game demo

Together with artists from our company Cat-astrophe Games we are working now on a big upgrade to “FPS game” example! Please welcome Adrianna Matejek (concept art, 2D, UI) and Alya Vaneskehyan (3D, textures). They will commit lots of things to fps-game-upgrade branch in the upcoming weeks πŸ™‚

Together we have a great plan how to turn this small example into a cool and impressive short 3D game.

Along with graphical upgrades, there will be functional upgrades. The “easy creature AI, as behaviors” will finally be done along with this rework.

Here’s a teaser — first 2 concept arts from Ada!

Note: I uploaded a really high-res version of these concept arts here. You can click on the image and download a full version.

If you like this, please support us on Patreon. This is exactly why we need your support — to afford to hire more and more talented people to work on CGE!

Comments on the forum ➀

CGE downloads now come bundled with latest stable version of FPC

Posted on

FPC logo

Our default downloads are now bundled with latest stable version of FPC (Free Pascal Compiler, an open-source cross-platform compiler that we love and recommend).

The goal is to make Castle Game Engine work out-of-the-box. Building and running a newly-created project from CGE editor will now work out-of-the-box, users don’t need to install their own FPC version. Downloading CGE gives you all you need to perform basic “workflow” with CGE editor: create new project from template, open and edit some design, hit F9 and see it build + run.

This should be great for users that don’t come with existing knowledge of Pascal ecosystem, who don’t want to (or maybe, just today, don’t care) about what FPC or Delphi version they use — they “just want to build CGE application”. Now they don’t need to learn how to install FPC, Lazarus or Delphi. They can just use CGE to build projects immediately. This is also great for people who may not need to edit the game — e.g. if you cooperate on a project with artists, who test the game in the editor, then they just want to edit some designs, and run the game by F9.

Note: You don’t need to use this “bundled” version of FPC of course. You can still use your own FPC or Delphi, we still support many compiler versions. You can still install them however you want (e.g. maybe using fpcupdeluxe). In this case, you also don’t need to download the “bundled” version, just download the unbundled versions from GitHub releases.

Underneath, the “bundled” FPC is stored in tools/contrib/fpc/ . If we don’t find other FPC installation, we will use this one. Moreover, we automatically pass proper -Fu for the compiler in such “bundled” subdirectory (as it doesn’t have any useful FPC config).

Comments on the forum (2) ➀

Published state fields are now automatically initialized, no need in most cases for DesignedComponent calls

Posted on

Van Gogh , Bedroom in Arles , night - by ruslans3d from https://sketchfab.com/3d-models/van-gogh-bedroom-in-arles-night-7c28126099404406bd0f5c150d809394

This is another important “quality of life” improvement for developers:

You no longer need to explicitly initialize the components you want to access using DesignedComponent method. You just need to move your fields to the published section to make them initialized automatically.

Detailed explanation of the difference

All (or most) of the calls like below can be now removed:

LabelFps := DesignedComponent('LabelFps') as TCastleLabel;

Previously, we advised to organize your state like this:

type
  TStateMain = class(TUIState)
  private
    { Components designed using CGE editor, loaded from gamestatemain.castle-user-interface. }
    LabelFps: TCastleLabel;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Start; override;
  end;
 
constructor TStateMain.Create(AOwner: TComponent);
begin
  inherited;
  DesignUrl := 'castle-data:/gamestatemain.castle-user-interface';
end;
 
procedure TStateMain.Start;
begin
  inherited;
  { Find components, by name, that we need to access from code }
  LabelFps := DesignedComponent('LabelFps') as TCastleLabel;
end;

Now, we advise a simpler approach:

type
  TStateMain = class(TUIState)
  published
    { Components designed using CGE editor.
      These fields will be automatically initialized at Start. }
    LabelFps: TCastleLabel;
  public
    constructor Create(AOwner: TComponent); override;
  end;
 
constructor TStateMain.Create(AOwner: TComponent);
begin
  inherited;
  DesignUrl := 'castle-data:/gamestatemain.castle-user-interface';
end;

Of course you may still find it useful to define Start method, to initialize various things about your state. But there’s no need for it if it was only doing DesignedComponent calls.

What’s going on under the hood

The published fields of the TUIState descendants are now automatically initialized when the design is loaded. Right before Start, the published fields (that have names matching some object in the design) are now automatically set to the corresponding objects. At Stop (when design is unloaded) these fields are set to nil.

As a bonus (advantage over previous solution) this avoids having dangling references after Stop. While previously you could set all your references to nil manually in Stop method… likely nobody did it, as it was a tiresome and usually pointless job. Now they are nil after Stop automatically, so accessing them will result in clearer errors (and can be safeguarded by X <> nil reliably).

I should also mention one disadvantage from the previous approach: if you make a typo in component name, e.g. declare BabelFps instead of LabelFps, then the mistakenly-named field will just remain uninitialized. Nothing will make an automatic exception like “BabelFps not initialized!”. Of course any code doing BabelFps.Caption := 'aaa'; will crash and the debugger should clearly show that BabelFps is nil. And you can write something like Assert(BabelFps <> nil); in Start to get explicit exception in case of mistake.

This is very consistent with how Delphi VCL and Lazarus LCL initialize their form fields.

Our conventions — where to put the published section?

I admit I had a little discussion with myself about “where to put the published section”?

Following our usual conventions for writing components, the published section should go as last. We usually write private, then public, then published. So I wanted to have section in the increasing order of “being exposed”:

type
  TStateMain = class(TUIState)
  // MOST INTERNAL
  private
    MyInternalStuff: Integer;
  // EXPOSED TO OUTSIDE WORLD
  public
    constructor Create(AOwner: TComponent); override;
  // EXPOSED TO OUTSIDE WORLD ALSO THROUGH RTTI
  published
    { Components designed using CGE editor.
      These fields will be automatically initialized at Start. }
    LabelFps: TCastleLabel;
  end;

But eventually I came to the conclusion that it is a bit unnatural in this case. Basically, Delphi VCL and Lazarus LCL are right to put it at the beginning. Because in the usual case, you don’t think about this published section as “the most exposed identifiers for outside code”. You think about it as “internal components I need to access to implement my design”.

And it’s kind of an “unfortunate but sensible limitation” that it means that these things have to be also exposed to everything from the outside. This fact makes sense if you realize that the automatic initialization requires RTTI (RunTime Type Information, known also as reflection in various other languages). Things that RTTI has access to are naturally available to the outside world, through RTTI. So it would not be consistent for compiler to “hide” the fields in the published section while still making these identifiers available through RTTI.

Yet, when creating Delphi VCL form, or Lazarus LCL form, or CGE state, you usually don’t really want to “expose” these fields to the outside world. You want to access them right within your form / state. Thus, having them at the beginning of the state makes sense. And is consistent with Delphi VCL / Lazarus LCL as a bonus.

Still I decided to explicitly spell the published section name everywhere. This allows me to easily say in documentation “put your field in the published section”. I don’t need to say “initial section” or “automatic section” and users don’t need to understand how it works and how {$M+} in Pascal works and whether TUIState was compiled with {$M+}. So, in the end, I propose to write:

type
  TStateMain = class(TUIState)
  published
    { Components designed using CGE editor.
      These fields will be automatically initialized at Start. }
    LabelFps: TCastleLabel;
  private
    MyInternalStuff: Integer;
  public
    constructor Create(AOwner: TComponent); override;
  end;

Have fun with this! I have already updated our templates, our manual like here, and some (but not all!) examples to follow the new convention.

Comments on the forum (13) ➀