Project layout

General FreeBASIC programming questions.
pestery
Posts: 493
Joined: Jun 16, 2007 2:00
Location: Australia

Re: Project layout

Postby pestery » May 30, 2012 3:21

Yep, Extern in the .bi and Dim in the .bas (or in the .bi but with #if guarding it so it's only defined once). Or you can use Common in the .bi and nothing in the .bas, but then you can't use constructors and destructors with the datatype. In general, never use an unguarded Dim in a .bi file if the file is used by more that one module (fbc mod1.bas mod2.bas mod3...). Quick example:

Code: Select all

compile with: fbc main-mod.bas module1.bas

' --- header.bi ---
Extern text As String
Common Shared value As Integer
Declare Sub set_stuff()

' --- main-mod.bas ---
#Include "header.bi"
Dim text As String
set_stuff()
Print "text = " & text
Print "value = " & value
Sleep

' --- module1.bas ---
#Include "header.bi"
Sub set_stuff()
   text = "Hello world"
   value = 10
End Sub

codeFoil wrote:The end result is never as pretty as I'd like it be, so the next time around, I try something slightly different.
I do the same thing :-)
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Project layout

Postby TESLACOIL » May 30, 2012 10:42

If you know exactly what kind of game engine you are building....would help if you told us a bit more about it

then you can have a look through and examine which features can be externalized and which features need to be tightly bound

If its not intended for others to use then you can create a dozen or more separate exe.s that can handle all the external stuff and just pass parameters via .ini / .txt files ( this makes it very easy to build and track down problems as there are dozens of data walls )

If it is intended for others to use, and perhaps alter the source to, then you have to put a lot more effort into , variable names, file names, and the architecture and documentation maps. You can have the best game engine in the world but if someone has to wade through and reverse engineer your code just to understand how to use it few if any ever will. Extensive documentation and video tutorial essential.




I have two big projects , my AI which runs on network and a 'big' space game which is multiplayer

wiki for my space game ( im really taking my time with this, lots of planning & testing before i write any serious code )
http://homeworlds.wikispaces.com/

Both projects are for real world deployment, the AI is a fully functional demonstrator , and the game is meant to be played by people who like to play space games, that is my target audience
petan
Posts: 683
Joined: Feb 16, 2010 15:34
Location: Europe
Contact:

Re: Project layout

Postby petan » May 30, 2012 13:09

Umm, here is a bit more concrete example with 5 modules for small&mid-project layout.
Variable modconf is built-in and fully visible/operable/changeable in ALL modules.
Tested on Linux.
Compiler directive "fbc -s gui myProggy.bas". Done

myProggy.bas file

Code: Select all

' some comments +
' notes to program +
' ideas +
' thoughts +
' todo +
' version number +,... I don't know ;)

'here move all Type xy, Dim shared xy, Declare xy SUB's+Func's,some fundamental SUB's+Func's bodies
#include "myBase1.bas"           
#include "myMath.bas"             'next part of SUB's+Func's bodies - math routines
#include "myStats.bas"             'next part of SUB's+Func's bodies - statistical routines
#include "my4D_visio.bas"             'next part of SUB's+Func's bodies - for 4D visualisation
#include "myNetty.bas"             'the rest of SUB's+Func's bodies - for networking
#include "fbgfx.bi"
'#include another needed BI files

'screenres ...
screen 19
myThingyRunning()
?:? ,"finished !":sleep
close      'for sure
end
rem myProggy ended

myBase1.bas file

Code: Select all

const myColor=RGB(0,0,0)

Type modconfig2
   
   modname As integer
   modpath As integer
   
End Type

Dim Shared modconf As modconfig2

Dim Shared as integer id

Declare sub whichModule1()
Declare sub whichModule2()
Declare sub whichModule3()
Declare sub whichModule4()
Declare sub whichModule5()
Declare sub myThingyRunning()
rem Declare some fundamental SUB's+Func's headers
/'
rem some fundamental SUB's+Func's bodies
'/

' ****************************   whichModule1()    ************************
sub whichModule1()
   ?
   ? "I am in Base1 module"
   ? "modname was ";modconf.modname
   modconf.modname=1
   ? "modname is ";modconf.modname
   sleep
end sub

' ****************************   myThingyRunning()    ************************
sub myThingyRunning()
  'do something
   whichModule1()
   whichModule2()
   whichModule3()
   whichModule4()
   whichModule5()
end sub

myMath.bas file

Code: Select all

/'
'SUB's + Func
'/
sub whichModule2()
   ?
   ? "I am in myMath module"
   ? "modname was ";modconf.modname
   modconf.modname=2
   ? "modname is ";modconf.modname
   sleep
end sub

/'
Declare mathematical SUB's+Func's headers and move them to myBase1.bas module !
rem mathematical SUB's+Func's bodies
'/

myStats.bas file

Code: Select all

/'
'SUB's + Func
'/

sub whichModule3()
   ?   
   ? "I am in myStats module"
   ? "modname was ";modconf.modname
   modconf.modname=3
   ? "modname is ";modconf.modname
   sleep
end sub

/'
Declare your Statistical SUB's+Func's headers and move them to myBase1.bas module !
rem your Statistical SUB's+Func's bodies
'/

my4D_visio.bas file

Code: Select all

/'
'SUB's + Func
'/

sub whichModule4()
   ?   
   ? "I am in my4Dvisio module"
   ? "modname was ";modconf.modname
   modconf.modname=4
   ? "modname is ";modconf.modname
   sleep
end sub

/'
Declare your 4D visualisation SUB's+Func's headers and move them to myBase1.bas module !
rem your  4D visualisation SUB's+Func's bodies
'/

myNetty.bas file

Code: Select all

/'
'SUB's + Func
'/
sub whichModule5()
   ?
   ? "I am in myNetty module"
   ? "modname was ";modconf.modname
   modconf.modname=5
   ? "modname is ";modconf.modname
   sleep
end sub

/'
Declare networking SUB's+Func's headers and move them to myBase1.bas module !
rem networking SUB's+Func's bodies
'/


Pete
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: Project layout

Postby Gonzo » May 30, 2012 14:27

your version is what i used to do before, now i only include .bi files, and use extern and function prototypes for declarations
much like dkl, and what you should do in any C project =)
it seems to work well

#config.bi:
Declare Sub AddLog(ByRef l As String)

Extern As modconfig modconf

and so on =)
petan
Posts: 683
Joined: Feb 16, 2010 15:34
Location: Europe
Contact:

Re: Project layout

Postby petan » May 30, 2012 18:10

Thx, glad to hear you are moved from place.

Pete
elsairon
Posts: 207
Joined: Jul 02, 2005 14:51

Re: Project layout

Postby elsairon » Jun 09, 2012 0:40

I use a separate .bas file for each different section of code that has a distinct purpose, with a header file for each. Then I only need to include the dear files when one file needs to access functions in another file.

Currently my game code is separated into these files, with some having only a few functions and others with upwards to 30+
I have my error reporting and code tracing functions in util.bas which every other file uses. the others have header files included depending on what information each needs.

_main.bas
ai.bas
commands.bas
display.bas
effects.bas
files.bas
flags.bas
game_states.bas
items.bas
keyboard.bas
load_items.bas
load_mobs.bas
load_terrain.bas
los.bas
map.bas
maths.bas
menu.bas
messages.bas
mobs.bas
parse.bas
pathing.bas
targeting.bas
time.bas
util.bas

I also use a directory structure on disk that supports this, with;
- a /src folder for all the .bas files
- /inc folder for all the header .bi files
- /doc folder for all the notes and documentation I need
- /tools folder for all the code analysis programs, etc I make/use to analyze my program
- /dat folder for all the data files etc. my program needs to use
- a /wip folder for things I am trying out that I don't want in the main code area

Additionally I use source code control so I can see a history of all changes I've made to every file and easily fall back to a different version if I need to.

One other tool I have found immensely helpful as the project gets larger and larger is multi-file search tool. So you can find a specific function, variable etc. and all its references in every file in your program. This alone has saved me hours and hours of time.
Gonzo
Posts: 722
Joined: Dec 11, 2005 22:46

Re: Project layout

Postby Gonzo » Jun 09, 2012 1:14

I see, that is very helpful
TJF
Posts: 3502
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: Project layout

Postby TJF » Jun 09, 2012 7:50

elsairon wrote:One other tool I have found immensely helpful as the project gets larger and larger is multi-file search tool. So you can find a specific function, variable etc. and all its references in every file in your program. This alone has saved me hours and hours of time.

Yes, that's a helpful feature, but it should be integrated in the IDE. Geany IDE supports this out-of-the-box using grep (or find). By pressing <Shift><Control><F> it creates a list of all occurences of a symbol. When clicking at a line in the list Geany loads the file (if not opened allready) and jumps to the right line.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Project layout

Postby TESLACOIL » Jun 11, 2012 0:59

Config files .txt format

One handy trick i use a lot is to create paths.txt files , these files contains paths & misc variables i may wish to change a lot

By altering a single variable here i can ensure all modules that read data from this paths/config file will be updated with the new value. This is especially useful for variables that you need to tweak a lot, game stats for a character or items or if you add another module you can add the path to that module + any flags/switches/variables specific to that module

At the start of the program i read these in and display the paths, variable etc values in the 'console window'. As paths is a .txt file i can open it quickly open cut n paste or alter any variables without using notepad without having to load yet another file into the ide.

This is very handy as the 'console' sits in the background so i can see at a glance what key variable values are in use without having them take up room on the game screen itself....i even have a separate var.exe which runs in its own window whos task is to simply throw up all those variables in a large window that has no direct connection with the game window or game.exe In this way i can shift aside the game window or alt tab it and see the values of 100+ critical variables at a glance.


For the game installer i usually create directories named GFX or SFX , GFX_1 to whatever ( graphics, sounds etc)
I name the folders with an abbreviation related to the type of content they hold, little things but it all adds up

GFX8bit , GFX16bit, PNGbig, PNGsm etc

I usually have a trash can/wip folder or three inside each directory, this saves me from having to constantly rename sound and graphics files that are being refined as part of the playtesting



Workstation
if you've' more than one computer its kind of handy to set up a number of screens in a row, as an instant at a glance reminder
i have very long work station, so I have plenty of room for half a dozen screens keyboards and mice
using different speakers and different monitor resolutions helps with fine tuneing the gfx and audio
what looks and sounds awesome on one computer can look eye jarring or sound tinny or hissy on another
You can have the game running on machine while coding away on the other....i find this helps a lot !
Even if you are on a tight budget a sheet of MDF from you local hardware store + a few junky computers goes a long way


If your working on a big software project dont be shy of moving the furniture around to suit. I have the adjacent walls papered in A4 , hand written notes, sketches as well as computer printouts...all aids to clearing the brain fog

Once you have a cosy software studio setup then ' code fests' with like minded visitors becomes a pleasure rather than a chore. So i clear the decks and make sure everyone has a comfy seat, monitor , mouse mat what have you. I do a fair bit of LAN gaming as well, so if your guests have got back ache or wrist ache fun is short lived.

If you have your 'Project layout' plastered across several walls and screens it makes it a lot easier to communicate your ideas to other interested parties when they visit.....regardless of this obvious benefit, sat hunched over a computer buried in a corner with my mouse/kbd fighting for space is not my idea of creative heaven
badidea
Posts: 1704
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Project layout

Postby badidea » Jun 11, 2012 18:49

Geany IDE supports this out-of-the-box using grep (or find). By pressing <Shift><Control><F> it creates a list of all occurences of a symbol. When clicking at a line in the list Geany loads the file (if not opened allready) and jumps to the right line.

Nice, did not know that. Very useful.
marcov
Posts: 2814
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Project layout

Postby marcov » Jun 11, 2012 18:55

TESLACOIL wrote:Config files .txt format
One handy trick i use a lot is to create paths.txt files , these files contains paths & misc variables i may wish to change a lot


I'm not sure why it can't be dirs.txt?
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Re: Project layout

Postby 1000101 » Jun 11, 2012 22:14

I break individual parts into individual files. With large classes I will break it into several files all with a related directory structure. Using an IDE like FBEdit it makes it much simpler to develop projects. If a single part becomes more complex I may break it into it's own project and build it as a library. My UI library is broken into more then 60 files in a directory structure which makes finding individual functional components much easier. I follow a simple rule of no single module is more than 800-1000 lines. Any more than that and it should be separated into different modules of related functions.

ie:
ui
ui\main.bas
ui\inc
ui\inc\uiclass.bi
ui\uiclass
ui\uiclass\render.bas
ui\uiclass\rendermethod.bas
ui\uiclass\eventhandler.bas
ui\uiclass\callbacks.bas
etc

The point is to reduce development time by making each module obvious by filename as to what it contains and only contain the related functions. Your project file will contain the list of all the files to compile and how. Your includes contain your structures, constants, etc. Finally the modules include only what they need.

As to referencing data not internally contained, look up the extern keyword in the wiki. The linker will handle all external references and make it all work.

A final note, try to avoid globals. Sometimes you need a global and that is fine, but it is "better" to pass only the data required to function. This makes re-entry and recursion much simpler to handle in the long run as you can't inadvertently change a value you shouldn't. ByVal is your friend. Unless you need to modify the calling functions data, it is better to pass it by value instead of by reference (ByRef).
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Project layout

Postby TESLACOIL » Jun 12, 2012 8:36

ref paths.txt vs dirs.txt

i think i tend to go for truncated phonetics with my namings schemes rather than puter terminology...parvs rolls of the tongue easier when your talking yourself through the code....as in change path to

if you are sharing code work with others its probably best to be boring and stick to ' well known ' computer terms, so dirs, in this case would reduce confusion, paths.txt scrapes a pass, but mpdp.txt = ??? = my progs directory paths = telepathy required

im sure there a books as well as international standards on naming schemes




the way we speak about computers is somewhat different to what we write
marcov
Posts: 2814
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Project layout

Postby marcov » Jun 12, 2012 9:03

1000101 wrote:I break individual parts into individual files. With large classes I will break it into several files all with a related directory structure. Using an IDE like FBEdit it makes it much simpler to develop projects. If a single part becomes more complex I may break it into it's own project and build it as a library. My UI library is broken into more then 60 files in a directory structure which makes finding individual functional components much easier. I follow a simple rule of no single module is more than 800-1000 lines. Any more than that and it should be separated into different modules of related functions.


I think the defining part is if you use separate compilation units or not? Are multiple .o files generated, or just one, IOW can you compile the program in parts, or only in one go?


P.s. I've been monitoring this interesting thread intensively. As you might know I'm very interested in module systems.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

Re: Project layout

Postby TESLACOIL » Jun 12, 2012 11:32

The modules of my AI are mostly fairly short , often little more than complex functions or subroutines. I have some large modules which are many 1000s of lines long but this is highly repetitive code, so the overall complexity is quite low.

I have always used multiple exe's even with quite small and relatively simple programs, though this approach is only suitable for some types of software. For example i might have a high score table which is a stand alone exe , it is only called when the main game is over. I often have separate exe's for things like 'splash screens' , ' software configuration' , eg the config exe closes and launches the main exe

I try and keep the main modules as clutter free as possible, if i can chop the head and the tail off into separate exe's i will

I was into hobby coding way back & this was a method i developed for myself back then but this approach is still valid. Its also very useful if you have your software running in parallel on a network. If your thinking of hosting a game server this is one way of offloading some of the less time critical computation or ad hoc computation though it does introduce vulnerabilities if you are relying on one computer to make data available for another.

This could work well if you where using a second computer to constantly back up data from the first using read only. The second computer can sift through the saved data looking for errors or other trends in the data.

This is an additional way you can 'break down complexity' and spread it out so its more readable

Return to “General”

Who is online

Users browsing this forum: No registered users and 1 guest