How to organize a larger project

Hi,

These are a few impressions of my new project.

https://youtu.be/2n16tNjutwc

In the meantime it’s getting a bit confusing and slow because of the many objects and I think it’s allready 25% done. What is the best approach to a larger project? One GameView with all the objects and logic, or split into more GameViews “levels”, but I don’t want to have the same game logic in every GameView.

Maybe someone has a good idea for this problem.

2 Likes

That looks so cool! Wow!

About your question: I think it’ll be an exaggeration to say “no two big projects are alike” but in the end larger projects often require different organization of things, often aiming at how it’s convenient to work with this specific usecase.

A few general and very IMHO notes:

  1. Don’t keep game logic inside of one unit. It’s good at the beginning but quickly becomes almost impossible to maintain. If something can be “extracted” into a separate unit, it should be. It’s much easier to find “where the jump is implemented” if jump is inside PlayerMovement unit which is 500 lines long, than inside of the GameView unit which is 10k lines long.
  2. In my experience keeping all the game in a single view is more preferable. However, note that I’m mostly dealing with procedurally generated worlds. As such I don’t have a “world as view”. I believe you are following the latter concept, so I may recommend “keep everything related to the world in one view, and everything related to game logic in another”. This way you can “stack” two views on top of each other: you have GameView which makes use of all logic of controlling the player character, some global interactions, inventory and everything else and IslandView attached inside of it as a TCastleDesign which handles world-specific things like the mesh (obviously), some additional scripts required for this specific location.
  3. In larger projects it’s most important to have things “generic enough” and “easy to work with”. It’s a big change of “paradigm”. In other words, organization of the code must first make it easy for you, not follow some generic recommendations or patterns (note that patterns were invented as a solution to this kind of problems, so following some generic patterns will often end up in a more maintainable project, I only mean that it’s not a law to follow a pattern - if it doesn’t serve it purpose to make life easier for you in the long run, you shouldn’t stick to it “just to follow the pattern”).

For example in my current project the logic/views organization is this way:
ViewWelcome
|
V
ViewMainMenuViewOptions, ViewCredits
|
V
ViewGameViewPause, ViewEncyclopedia
|
MapInterface (something that can be called ViewMap, but it’s simply a UI element with custom rendering instead, will be reworked into a Viewport later) : this is something that in your case I’d propose to be ViewWorld.

2 Likes

Hi eugeneloza,

thank you for your help. I try to do one GameView for a level and also for the map and inventory. I have found a document how to handle Views, could be helpfull.

Looks absolutely cool, and a lot of work! There are a lot of features visible there, kudos.

In addition to above suggestions how to organize larger project:

1 Like

Hi there,

I have made now for the inventory a seperate view. This view gets the information from the “FirstLevelView”.
Everything works how it is written in the manuel “managing views”. It looks exactly the same as before.
Btw the TCastleDesign is very helpfull.

Is there a possibility to get the information which view is under the InventoryView or which view is calling the

Container.PushView();

Regards
Didi

You can look at the current “stack” of views, using

  • Container.ViewStack
  • Container.ViewStackCount

( Castle Game Engine: CastleUIControls: Class TCastleContainer )

And Container.FrontView (mostly a shortcut to Container.ViewStack[Container.ViewStackCount - 1] , but returns nil if stack is empty) should be most helpful:

The view in the front (top-most view on the stack).

In case you used PushView, this returns the top-most (most recently pushed) view.

I sometimes do check like

if Container.FrontView = Self then

to perform something only if current view is front, like here: castle-engine/examples/fps_game/code/gameviewplay.pas at master · castle-engine/castle-engine · GitHub . This is the logic of TViewPlay in our “fps_game” demo. This view is sometimes front (when you play the game), sometimes not front (when the “pause view” is on top).

Something you forgot is planification. That will help a lot organizing yor project. Knowing how many scenes, places, characters, items… before start writing code is essential to know how to organize both code and data. Also it will help you to see things that can be reused (by class inheritances or any other means).

1 Like