Forum > Games

Castle Game Engine (Cross Platform) - Need Help with Drawing a Raycast Vector

(1/28) > >>

Hi everyone,

I am new to these forums, but have experience in programming in many languages, like C++ or Python, using Windows computers.

I am using the Castle Game Engine to develop video games because it is 100% free and works on the very old and slow machines from the 90s, whereas most so-called professional game engines like Unity or Unreal 5 cost money or don't run on old machines you will find in most schools or homes.

The Castle Game Engine uses Pascal for its language and Lazarus for its compiler, and is cross platform, but because I am using it on a Windows computer I decided Windows forums would be most appropriate compared to "Miscallenous" which seems to be about non-home computer electronics specifically, and not cross-platform software.

I am having trouble with a project you can find on this link that you copy-paste into a new browser tab:, which I made free to download for everyone who has the Castle Game Engine downloaded on their computer - I made sure it actually opens on my copy correctly first obviously.

I posted the link this way as the direct link was removed for security purposes, which is fine and I understand why - it's for both the forum's and my own safety.

It is meant to be a third person game that is a platformer where you play as Sandy Cheeks from SpongeBob, like a kid friendly game.

I initially asked for help on this forum thread, again copy paste the link in a new tab cause direct links don't work for security reasons:, but got called unhelpful responses like "being a hopeless idiot who doesn't pay attention" by the so-called helpers, even after I used examples to prove I was paying attention.

I understand that their point was that I would not include certain lines that made the code not work the way it does, like not including the correct amount of "begins" and "ends", but I pointed out how I understood conceptually how a begin and end block was supposed to work, like how it begins and ends a specific block of code, or that a procedure is defined in a certain way always, and that it carries out a particular task with or without a certain number of inputs, I only needed help with the details.

This code snippet is what I need help with, in the line about gamemymesh.pas:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure CreateMesh;  begin    Mesh := TCastleRenderUnlitMesh.Create(true);    Mesh.SetVertexes([      Vector4(-1, -1, -1, 1),      Vector4( 1, -1, -1, 1),      Vector4( 1,  1, -1, 1),      Vector4(-1,  1, -1, 1),       Vector4(-1, -1,  1, 1),      Vector4( 1, -1,  1, 1),      Vector4( 1,  1,  1, 1),      Vector4(-1,  1,  1, 1)    ], false);    Mesh.SetIndexes([      // line loop on Z = -1      0, 1,      1, 2,      2, 3,      3, 0,       // line loop on Z = 1      4, 5,      5, 6,      6, 7,      7, 4,       // connect Z = -1 with Z = 1      0, 4,      1, 5,      2, 6,      3, 7    ]);     // Later on in the code    CreateMesh;

This is the relevant code snippets from the example I was using.

I learned that SetVertices sets each point of the fesh, and SetIndices sets how the points are connected and in what order, like I initiailly guessed, when I asked.

However, when I asked for clarification on how to get custom inputs to "SetVertices", which I needed to do to get the player character's location precisely drawn down,

I wasn't given any response, so I assumed it was because they wanted me to figure things out for myself like they told me explicitly many times earlier, which is fine.

I did the resourceful thing and looked up if that particular procedure came pre-coded with a particular number of inputs/parameters in the manual's API, and fortunately it wasn't, so I made an educated guess that it was just a function customly made for that particular piece of code,

So I defined my own version of it with arguments for getting the player Transform object's properties, and made sure that each input of the Vector4's were all of the same type, so single precision singles, like the API says should happen right on the page for Vector4 itself:

Like so:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- procedure CreateMesh(const AvatarTransform: TCastleTransform);  begin    Mesh := TCastleRenderUnlitMesh.Create(true);    Mesh.SetVertexes([      Vector4(0.0, AvatarTransform.Translation.Y, 0.0, 1.0),      Vector4(0.0, (AvatarTransform.Translation.Y - AvatarTransform.Direction.Y), 0.0, 1.0)    ], false);    Mesh.SetIndexes([      // line loop on Z = -1      0, 1    ]);   // Line somewhere later down the code; I guessed the problem was // not having the correct amount of inputs to match the procedure  // definition above, but it still doesn't draw anything afterward CreateMesh(AvatarTransform);
However, as mentioned in the comments in the code, even after I correctly specify the correct number of inputs when I call the newly made function, nothing happens at all, not even drawing small dots.

Again, if you want to test this yourself, simply open the Castle Game Engine and the project, copy and paste the code from the second snippet where appropriate in the first snippet, and witness for yourself how it compiles fine but doesn't actually do anything, when I was given that the first example worked perfectly as it was.

Does anyone with any expertise in Pascal Game Engine's Lazarus compiler in particular, know why the above code in the second snippet doesn't work?

I caught on that maybe changing the line about the direction to a "plus" the direction rather than "minus" the direction, might be part of the problem, but again at least something should have been drawn instead of nothing at all for the start point without the direction added, for example, and a line of some kind should still be there regardless of that detail.

I intentionally removed the "end" of the blocks because I wanted to focus on posting the minimal code necessary to reproduce the problem, trusting that the reader knows how to copy paste appropriate lines in the appropriate spots rather than just copy pasting the code exactly like that, and if you look at the full code in the project I attached, I have the end added correctly later on in the code.

To answer your main question:

You show how you setup the TCastleRenderUnlitMesh instance. But you don't show if (and where) do you call "Mesh.Render(pmLines)" which is necessary to actually render something. Possibly you just forgot it, which explains why you don't see anything.

If you are unsure how TCastleRenderUnlitMesh works, please:

* Experiment with CGE examples, in particular "examples/research_special_rendering_methods/test_rendering_opengl_capabilities" ( ) is using TCastleRenderUnlitMesh. You refer to it in your post, so I believe you found it. Note how has "Mesh.Render(pmLines)" call.
* See the API docs, . It says explicitly

--- Quote ---The things you really have to set before rendering are:
- Vertexes, using SetVertexes.
- Matrix (combined projection * camera * model transformation) ModelViewProjection.
- That's it, the rest has sensible defaults. You can just call Render.

--- End quote ---

* There is also another way to render lines in Castle Game Engine, using TLineSetNode class and friends. See how "SceneVisualizeVelocities" is set up in . This is part of a larger example examples/physics/physics_forces ( ).
Note: You didn't make accessible to public. In GDrive, select something like "Anyone with link: Can View" in sharing permissions. So I cannot see your complete source code. I'm only basing my answer on the code snippet you pasted.

To addreess some additional things you mention in this thread, about Castle Game Engine forum (latest thread with you: ):

* Nobody ever called you an "idiot". Never. I take moderation on all CGE channels seriously, and the short rule is simple: "disagreeing is always OK, being rude is never OK", and I'm happy that everyone (including you, to be clear) do follow it.

The only time this word was said was when you have started defending yourself a few times by saying "I am not a complete idiot" or similar things. See e.g. . But nobody called you that.
* We gave you a lot of support and we still patiently answer your questions. We have now a few *huge* threads on our forum, started by you and trying to help you. Me and at least 3 more people from community (from what I see in the threads) have been trying to help you:

* 270 posts on
* 114 posts on
* 110 posts on
* 93 posts (latest thread) on

* The above threads do not seem to end in a productive way.

It seems you are rather new to Pascal and programming. (This is not an accusation, just statement of the fact, shown in above threads -- we're happy to help you learn!) But it seems you are trying to write code by "trial and error". You are often blocked/surprised by simple compilation errors, and then you put too much effort (in my eyes) to defend your (invalid) code on our forum and claiming the compiler says nonsense or that some earlier post misled you. And too little effort to read about the related error message, experimenting with code, looking for explanation of the error and finding (correct, not "anything random that compiles"!) solution. The compiler is generally right, and you should follow on the error messages trying to fix them.

To this end, we did repeatedly ask you to learn Pascal first, pointing to multiple resources linked from . And I think you actually followed them to some extent, thank you -- but not enough.

As a result, you did get 1 answer saying "There is no hope. I am sorry" from one poster. That was not necessary, but I do not see a fault in that. We are at ~500 posts, and no indication of being able to solve actual problems together.

--- Quote ---.. like not including the correct amount of "begins" and "ends", but I pointed out how I understood conceptually how a begin and end block was supposed to work

--- End quote ---

In the latest thread on Castle Game Engine forum, , the last issue you are stuck with is a trivial compilation error. You act surprised that the code you show doesn't compile, yet it has a really trivial error. I gave you very explicit instructions how to solve it: you *literally* must count the "begin" and "end" in your code. They don't match. You started to do correct indentation, but didn't do it correctly, so your indentation is misleading you.

My last post there, that you haven't responded, asks you to do this -- literally count "begin" and "end" in your code. As I tell there, do it manually, and do it by Ctrl+F in any text editor, specialized for Pascal or not (VS Code, Notepad++, Lazarus IDE, Delphi IDE...).

See . Your last post *does not* have it correctly, .

Had a 'looksee' at the last post and did some formatting and found your missing end, here it is:
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---begin  inherited;  { This virtual method is executed every frame (many times per second). }  SandyIdling := 0;  SandyAirborne := 0;  MaxDistance := 0.3;  MoveAmount := Vector3(0, -5, 0);  RayCastDirection := Vector3(0, -1, 0);  RayCastResult := AvatarRigidBody.PhysicsRayCast(    (AvatarTransform.Translation),    RayCastDirection,    0.3  );  if RayCastResult.Hit then  begin //1    SandyAirborne := 0;    LabelFps.Caption := 'FPS: PLACEHOLDER';    if SandyIdling = 0 then    begin //2      SandyIdling := 1;      SandyLegs.PlayAnimation('LEGS_IDLE', true);      SandyTorso.PlayAnimation('TORSO_IDLE', true);    end //2  end; //1 <<<<----- THIS ONE WAS MISSING!!!!  else  begin //3     SandyIdling := 0; { this I moved from the line above 'begin' 15.02.24 /bc }    if SandyAirborne = 0 then    begin //4      SandyAirborne := 1;      SandyTorso.PlayAnimation('TORSO_AIRBORNE', true);      SandyLegs.PlayAnimation('LEGS_AIRBORNE', true);    end; //4    AvatarTransform.Move(MoveAmount, false, true);    LabelFps.Caption := 'FPS: ' + Container.Fps.ToString  end; //3  // UpdateAimAvatar;end;  I hope I'm not intruding...?
Regards Benny

To michaelis: I did review the begins and ends, as pointed out in the thread, and although the word "idiot" wasn't used verbatim calling someone hopless when they are patiently pointing out the facts is saying exactly the same thing.

I understand he did it only once, but once is still too much/enough, especially because I was just using the facts.

I got a reply on another forum thread that I included the wrong amount of "ends", like you suggested, and that helped, but again when I checked in the compiler I got that every begin was highlighted with a red rectangle with another end that was also highlighted in the same way, like the compiler was showing me every "begin" had an "end" associated, so I didn't see what was wrong at first.

For the new problem, I am very sorry if I didn't make this 100% clear even though I tried to, but I only included the minimum amount of code relevant to the problem at hand and nothing more, and because "Mesh.Render(pmLines)" was exactly the same way in both lines, I used deductive reasoning/logic to guess that if a piece of code works correcly as it was, then it couldn't be part of the problem after changing other pieces of code; the problem had to be with the changed pieces.

Again, this kind of stuff is common sense and you understand, but the so-called "helper" calling me hopeless wouldn't listen when I pointed this out to him in many of the threads.

To cdbc:

Thank you so so much for your patient and thoughtful response! You're the best helper a newcomer to Pascal can help for :)


[0] Message Index

[#] Next page

Go to full version