# You favorite instrument for working with Strings

**URL:** <https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424>\
**Category:** Uncategorized\
**Created:** [November 10, 2024, 8:53pm UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424 "2024-11-10T20:53:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Noscow](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/noscow/32/964_2.png) [@Noscow](https://forum.castle-engine.io/u/Noscow)\
**Post date:** [November 10, 2024, 8:53pm UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/1 "2024-11-10T20:53:37Z")

</div>

Good day!  
I have few configuration files with information about the game objects. So, when game starts I need to load and read (and sometimes save) lot of information.  
For now I use few my custom procedures. But I want the more optimal instrument.  
What you use in the you projects? For now I look to the TStringList and other standard Pascal things. Is they fast and effective enough for the load and save game resources? Or you prefer to make only necessary procedures by yourself?

---

<div class="post-metadata">

**Author:** ![kagamma](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/kagamma/32/226_2.png) [@kagamma](https://forum.castle-engine.io/u/kagamma)\
**Post date:** [November 11, 2024, 7:49am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/2 "2024-11-11T07:49:19Z")

</div>

Personally I rely on object serialization/deserialization for saving and loading game states, see [Streaming components - Free Pascal wiki](https://wiki.lazarus.freepascal.org/Streaming_components) and [Streaming JSON - Free Pascal wiki](https://wiki.lazarus.freepascal.org/Streaming_JSON) . This is used by both Lazarus LCL (save & load form resources) and CGE (save & load design files) so it is battle-tested and effective.

---

<div class="post-metadata">

**Author:** ![Didi](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/didi/32/1908_2.png) [@Didi](https://forum.castle-engine.io/u/Didi)\
**Post date:** [November 11, 2024, 8:57am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/3 "2024-11-11T08:57:58Z")

</div>

I use also the TStringList and text files (or csv). In my projects I need only some values to store the options, highscores or levels. Read/write on text files is for me very fast and I tried with hundrets of lines. But if you need to join some information from different data files (like tables) I would go with sqlite database. It is easy to use and makes fun to write sql. 🤔

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [November 12, 2024, 4:31pm UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/4 "2024-11-12T16:31:58Z")

</div>

Personally I would recommend to define components with published properties and then you can use CGE serialization/deserialization to read them (`CastleComponentSerialize` with `ComponentLoad`, `ComponentSave`). Like

```delphi
type
  TMyGameConfiguration = class(TCastleComponent)
  private
    FMonsterSpeed: Single;
    FPlayerSpeed: Single;
    FDefaultMonster: TMonster;
  published
    property MonsterSpeed: Single read FMonsterSpeed write FMonsterSpeed;
    property PlayerSpeed: Single read FPlayerSpeed write FPlayerSpeed;
    property DefaultMonster: TMonster read FDefaultMonster write FDefaultMonster;
  end;

```

and load like

```auto
MyConfig := ComponentLoad(
  'castle-data:/my_config.castle-component', SomeOwner) 
  as TMyGameConfiguration;

```

Advantages:

- You can make it as simple or as complicated as you want 🙂 That is, TMyGameConfiguration can have just simple properties (strings, floats, integers) but it can also refer to other components. There is documentation how to make components in [Custom Components | Manual | Castle Game Engine](https://castle-engine.io/custom_components) .

- You also have ability to make CGE editor aware of them (again see [Custom Components | Manual | Castle Game Engine](https://castle-engine.io/custom_components) ) and then even allow game designers to configure your objects using CGE editor’s object inspector, so it’s more visual to them. It’s an option – you don’t need to use this option.

- The serialization / deserialization of CGE components uses FpJsonRtti and it results in relatively “regular” JSON files. So if you want to later edit them by hand, in any text editor, grep them etc. – no a problem, you just have text files.

- You can save components “on their own” (like in above example `my_config.castle-component`) or attach them to other components (like particular creatures) using TCatleComponent.NonVisualComponents.

- If you want your things to be more than only data, you can also consider using behaviors, [Behaviors | Manual | Castle Game Engine](https://castle-engine.io/behaviors) , that (by convention) also make some behavior based on their properties.

This also matches how we did game configurations in games using Unity, back when I was working with Unity 🙂 Exposing parameters by public fields in MonoBehavior, allowing game designers to tweak them in Unity Editor visually → this was powerful and easy to use by game designers. What I described above → is mostly an equivalent to this in _Castle Game Engine_.

---

<div class="post-metadata">

**Author:** ![Didi](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/didi/32/1908_2.png) [@Didi](https://forum.castle-engine.io/u/Didi)\
**Post date:** [November 15, 2024, 8:01am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/5 "2024-11-15T08:01:15Z")

</div>

You are right, there are some advantages when using components with published properties. You do not need to know the file structure.

I tried your example:

```auto
  if event.IsKey(keyC) then
  begin
    MyConfig:=TMyGameConfiguration.Create(self);
    MyConfig:=ComponentLoad('castle-data:/my_config.castle-component',Self) as TMyGameConfiguration;
    label2.Caption:=Ord(MyConfig.DefaultMonster).ToString + ' ' + MyConfig.PlayerSpeed.ToString+ ' ' + MyConfig.MonsterSpeed.ToString;
    MyConfig.Free;
    Exit(true);
  end;

```

1. Is it recommended to free the MyConfig after the load, or can I use MyConfig as long as the view is running and I free it when the view is closing?
2. Did I understand this right, that it could be possible to make this available in the editor? Some hints to do this?

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [November 15, 2024, 10:59am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/6 "2024-11-15T10:59:31Z")

</div>

> [@Didi](#):
>
> - Is it recommended to free the MyConfig after the load, or can I use MyConfig as long as the view is running and I free it when the view is closing?

You can keep the `MyConfig` existing as long as you wish, there are no limits here. You can keep it until the view stops.

Or even longer: you can load it in `ApplicationInitialize` (if you use the default CGE new project setup, this is a routine inside `GameInitialize` unit that is assigned to `Application.OnInitialize`) and create `MyConfig` there, using the `Application` (singleton in `CastleWindow` unit) as the owner:

```auto
MyConfig:=TMyGameConfiguration.Create(Application);

```

Thsi way, MyConfig can just “live” throughout the entire application.

You can define a trivial unit like

```auto
unit GameConfig;
interface
type
  TMyGameConfiguration = class(TCastleComponent)
    ...
  end;
var 
  MyConfig: TMyGameConfiguration;
implementation
end.

```

to have the singleton `MyConfig` available for all the units (including view) code without any hassle.

> [@Didi](#):
>
> - Did I understand this right, that it could be possible to make this available in the editor? Some hints to do this?

See the [Custom Components | Manual | Castle Game Engine](https://castle-engine.io/custom_components) , esp. initial sections _" Example of custom component and its registration"_, _" Running editor with custom components"_.

The short version, adjusted to example above, is:

- Add something like

- In `CastleEngineManifest.xml`, add `editor_units="GameConfig"`

- Now open the project in CGE editor - it should propose to rebuild editor, and the new editor will have a new component called “My Game Configuration” using your code from `GameConfig`.

- You can create a new design using this component, using menu item _“Design → New Non-Visual Component (Custom Root) → My Game Configuration”_. And thus you will have the object inspector to visually editor all published TMyGameConfiguration properties.

- You can save the file as `my_config.castle-component` and from code load it using your code from above post. In the future, you can just open your project in CGE editor, double-click on `my_config.castle-component` in CGE editor “Files” panel, and edit it.

---

<div class="post-metadata">

**Author:** ![Noscow](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/noscow/32/964_2.png) [@Noscow](https://forum.castle-engine.io/u/Noscow)\
**Post date:** [November 18, 2024, 10:12am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/7 "2024-11-18T10:12:22Z")

</div>

So, I will try the few above approaches.  
I think `TCastleComponent` will more useful for game settings.  
And for the game maps I will use strings from files with special format - for now it still more easy for me, especially for potential modding without CGE API.

---

<div class="post-metadata">

**Author:** ![Didi](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/didi/32/1908_2.png) [@Didi](https://forum.castle-engine.io/u/Didi)\
**Post date:** [November 19, 2024, 1:21pm UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/8 "2024-11-19T13:21:29Z")

</div>

it works, for simple properties. But if I want to write the highscore data, I have to define 60 properties (10 lines with 6 properties each).  
Then I tried this:

 ![grafik](https://forum.castle-engine.io/uploads/default/original/2X/0/00220dbc751fdd42bfcf8b9bae9300f836423f04.png)

```auto

  if event.IsKey(keyH) then
  begin
    MyConfig:=TMyGameConfiguration.Create(self);
    MyHighscore:=TCastleComponent.Create(self);
    MyHighscore:=ComponentLoad('castle-data:/highscore1.castle-component',Self) as TCastleComponent;
    MyConfig:= MyHighscore.NonVisualComponents[6] as TMyGameConfiguration; {line 7 from the higscore file "highscore1.castle-component" }

    label2.Caption:=MyConfig.Monsterspeed1.ToString + ' ' + MyConfig.Monsterspeed2.ToString+ ' ' + MyConfig.Monsterspeed3.ToString + LineEnding +
                    ord(MyConfig.MonsterType1).ToString + ' ' + ord(MyConfig.MonsterType2).ToString+ ' ' + ord(MyConfig.MonsterType3).ToString + LineEnding +
                    MyConfig.MonsterStrengh1.ToString + ' ' + MyConfig.MonsterStrengh2.ToString+ ' ' + MyConfig.MonsterStrengh3.ToString;

    MyHighscore.Free;
    MyConfig.Free;
    Exit(true);
  end;

```

It seems to work correct. The values of the line 7 from highscore are shown.  
Is there a better solution?

---

<div class="post-metadata">

**Author:** ![kagamma](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/kagamma/32/226_2.png) [@kagamma](https://forum.castle-engine.io/u/kagamma)\
**Post date:** [November 19, 2024, 3:53pm UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/9 "2024-11-19T15:53:09Z")

</div>

A more elegant way is to use [TCollection](https://www.freepascal.org/docs-html/rtl/classes/tcollection.html), which allows you to define complex properties. You can use it to store an array of TMyGameConfiguration.

Basically you create a new TCollection property (HighScores , for example):

> property HighScores : TCollection read FHighScores ;

Then you initialize HighScores in your component’s Constructor method (remember to free it in Destructor method):

> FHighScores := TCollection.Create(TMyGameConfiguration);

After that you can edit it freely in castle-editor.

Example with `Anchors` as a TCollection:

 ![image](https://forum.castle-engine.io/uploads/default/original/2X/e/e2afe9c30a3eff709345af8a79aeb21e560985a1.png)

Edit: Forget to mention, TMyGameConfiguration must be a descendant of TCollectionItem.

---

<div class="post-metadata">

**Author:** ![michalis](https://forum.castle-engine.io/user_avatar/forum.castle-engine.io/michalis/32/3_2.png) [@michalis](https://forum.castle-engine.io/u/michalis)\
**Post date:** [November 20, 2024, 11:51am UTC](https://forum.castle-engine.io/t/you-favorite-instrument-for-working-with-strings/1424/10 "2024-11-20T11:51:11Z")

</div>

Indeed, so we have 2 ways of effectively have a “list of X, that can visually configured using CGE editor”.

1. One is to use `NonVisualComponents` which are a list, as @Didi shows.

2. Another is to define properties of type [TCollection](https://wiki.freepascal.org/TCollection) as @kagamma shows. It means you can have as many `TCollection` instances as you want and they have clear names, like `HighScores` in the example. I agree this looks cleaner than `NonVisualComponents` 🙂

I wanted to add we have a TODO in roadmap that will become the 3rd and recommended answer, once implemented: [`TCastleComponentList<T>`](https://castle-engine.io/roadmap#component_list). See the description in that page about my plans and reasons. This is explicitly something like _“our TCollection, with some advantages (I explicitly added a note about this at the end to that section)”_.
