Error creating "I" for a for loop

I’m reading from the manual in section 10of this page:
https://castle-engine.io/viewport_and_scenes_from_code

The manual says to create multiple instances of a scene with a for loop in TStateMain.Start. When I try to compile, the “I” in " for I := " gives me this error:

gamestatemain.pas(65,5) Error: Identifier not found “I”
gamestatemain.pas(65,5) Error: Ordinal expression expected
gamestatemain.pas(65,5) Error: Illegal counter variable
(…followed by more errors pertaining to the missing indentifier…)

I tried declaring “I” as a variable first:

var
   I: integer;

and then I get this error:

gamestatemain.pas(62,1) Error: Illegal expression
gamestatemain.pas(63,4) Fatal: Syntax error, “;” expected but “identifier I” found

I thought declaring counter variables within the syntax of the for loop was generally the proper convention. I don’t know what to do to get it to compile. Here is what my code looks like presently:

{var
   I: integer;}

for I := Low(CarTransforms) to High(CarTransforms) do
  begin
       CarTransforms[I] := TCastleTransform.Create(Application);
       CarTransforms[I].Translation := Vector3((Random(4) - 2) * 6, 0, RandomFloatRange(-70, 50));
       CarTransforms[I].Add(CarScene);
       Viewport.Items.Add(CarTransforms[I]);
  end;

Could someone give me some guidance/clarify what is wrong?

In Pascal you have to declare variables in a special place, not just anywhere like in C#. E.g. in your situation it would be something like:

procedure TStateMain.Start;
var
  I: Integer; // before "begin"
begin
  inherited; // note this thing, it's important to call parent's Start, it's like base.Start() in C#

  for I := Low(CarTransforms) to High(CarTransforms) do
  begin
       CarTransforms[I] := TCastleTransform.Create(Application);
       CarTransforms[I].Translation := Vector3((Random(4) - 2) * 6, 0, RandomFloatRange(-70, 50));
       CarTransforms[I].Add(CarScene);
       Viewport.Items.Add(CarTransforms[I]);
  end;
end;

Hi eugeneloza. Thanks for explaining that! I had decided to focus on the CGE tutorials first and then go do some more focused study on learning pascal, but it looks like maybe I should do that first.

I moved the integer declaration up to the position you demonstrated, and now the for loops itself gives no errors, but it appears to have broken everything else.

gamestatemain.pas(65,52) Error: Identifier not found “Application”
gamestatemain.pas(66,72) Error: Identifier not found “RandomFloatRange”
gamestatemain.pas(68,8) Error: Identifier not found “Viewport”
gamestatemain.pas(88,12) Error: Methods can be only in other methods called direct with type identifier of the class
gamestatemain.pas(90,3) Error: Identifier not found “LabelFps”
gamestatemain.pas(90,33) Error: Identifier not found “Container”
gamestatemain.pas(92,16) Error: Identifier not found “CarTransforms”
gamestatemain.pas(92,39) Error: Identifier not found “CarTransforms”
gamestatemain.pas(93,7) Error: Identifier not found “UpdateCarTransform”
gamestatemain.pas(93,26) Error: Identifier not found “CarTransforms”
gamestatemain.pas(94,4) Fatal: Syntax error, “.” expected but “;” found

I’ll take another shot at this when I can write pascal without needing my hand held. Thanks for your help!

The compiler first looks for obvious errors in the code (like using wrong syntax), and if there are none, then tries to look for more complex ones. So, what happened next: 1) your uses section is not filled in properly and 2) you don’t seem to be working inside of a proper TUiState class.

It may get a bit confusing if I’ll try to explain those. You’ll need to get acquainted with several principles of programming in Pascal. I’m not sure if you have background in some other programming language (am I correct in guessing it’s C#?), but you might find useful this book by @michalis Modern Object Pascal Introduction for Programmers | Castle Game Engine

Namely your issues are addressed in Modern Object Pascal Introduction for Programmers | Castle Game Engine and Modern Object Pascal Introduction for Programmers | Castle Game Engine

What exactly the errors that you’ve received mean is:

  • gamestatemain.pas(65,52) Error: Identifier not found “Application” ----------- means you didn’t include CastleWindow unit in uses section.
  • gamestatemain.pas(66,72) Error: Identifier not found “RandomFloatRange” ----------- means you didn’t include CastleUtils unit in uses section.

Next errors mean that you are doing something not inside your “State” class but inside some other procedure, or in method of a class that does not inherit from TUiState.

  • gamestatemain.pas(68,8) Error: Identifier not found “Viewport”
  • gamestatemain.pas(90,3) Error: Identifier not found “LabelFps”
  • gamestatemain.pas(90,33) Error: Identifier not found “Container”

The next errors mean that you reference some variables/classes/methods that do not exist in the current context. Maybe this is consequence of the previous bug, or maybe you just didn’t declare them yet:

  • gamestatemain.pas(92,16) Error: Identifier not found “CarTransforms”
  • gamestatemain.pas(92,39) Error: Identifier not found “CarTransforms”
  • gamestatemain.pas(93,7) Error: Identifier not found “UpdateCarTransform”
  • gamestatemain.pas(93,26) Error: Identifier not found “CarTransforms”

Finally this one means that you have unmatching beginend pairs, or otherwise some other required “end” is missing.

  • gamestatemain.pas(94,4) Fatal: Syntax error, “.” expected but “;” found

Note that the manual has a hint to add units to uses clause, and how to find them:

Remember to add the necessary units to your uses clause to have the appropriate identifiers defined. If you follow the reference links, like this one: TCastleScene, then you will see in which unit is each identifier defined. TCastleScene class is part of the CastleScene unit. TCastleViewport is part of the CastleViewport unit.

(Read it with links, point 5 of " 5. Refer to the designed components" on Writing code to modify scenes and transformations | Manual | Castle Game Engine ).

In the past, I was writing which units exactly to add to the uses clause in manual – but occasionally this information was outdated by next engine versions. So I decided to give here a “fishing rod”, not a “fish”, to readers :slight_smile: Hopefully you can figure it out (of course let us know if not).

If you get stuck, remember that there’s an example project in engine code ( castle-engine/examples/viewport_and_scenes/cars_demo at master · castle-engine/castle-engine · GitHub , open examples/viewport_and_scenes/cars_demo if you already have CGE) that does everything described in that manual page. You can just explore code/gamestatemain.pas inside, https://github.com/castle-engine/castle-engine/blob/master/examples/viewport_and_scenes/cars_demo/code/gamestatemain.pas .