I should write up some tips for everyone who wants to make a driving game. I think I will.
This is my area, something which is a part of every day in my life; I know what it feels like to think about getting into making a driving game.
I am making a car racing game as part of my multi-sports game. I have created cars, AI, roads, checkpoints and so on; getting them to work and making things look good.
The problem with working on your own is that you have to do EVERYTHING! Modelling, programming, audio, testing and tweaking.
You will be very surprised at how difficult the testing and tweaking part is in driving games. When it comes to getting the car to feel the way you want it to feel; to not spin and topple over when a wheel touches pebble; to not total when you make a sharp turn, and as for getting the gears and audio to work to change speed; yikes! Hard, hard work.
If you want to make a start, FIRST thing to stress is not to give up and not to work on more than one project if you can; you can end up spending your life working on more 'new projects'.
On a practical basis, these procedures will get your racing game up and running. If you are using Windows 7 / 8; I recommend not installing the game studio in the 'Program Files' folder or in any other Windows location under protection, by default the operating system is set up to protect itself from tampering, and the game studio needs freedom to produce executables. Excluding the TGC folder and your project folder in your anti-virus is a good idea. Lots of .EXE files will be compiled there; just make sure your internet download folder is not excluded also!
A: You need good equipment; duh yeah! But seriously don't under estimate it. You need to run the game whilst running some kind of physics editor for your engine tweaking; in addition to running Blender and your IDE whilst making an analysis of visuals and game-flow.
You will be compiling code many times, light-mapping your levels, exporting vehicles from blender; you truly have a need for speed! You are unlikely to build something that runs perfectly straight away, this means you need more power to make up for your mistakes. Get a decent PC, or two, and some file backup equipment; sometimes hard-drives crash, sometimes viruses do get on your system, sometimes graphics cards burnout. Backup every day as a minimum; if you spend lots of time on the work.
B: Install Blender, TGC products and your project on a separate hard drive from your operating system if you can; this reserves more disk IO speed for your work instead of sharing the disk with background processes and your web browser. I partition my drives so that fragmentation is limited to particular partitions; and that's the setup over with.
C: Learn the basics; start with learning how to use arrays, functions, timers, 3D objects and sounds. Here are some good tutorials and examples. These are not driving game tutorials, but they are necessary to get any game to work. There are other tutorials around that may not have sprung to mind; but these are important.
You will not read/watch them all, unless you are perfect; just try to at least skim through them to take note of the principles.
Daniel's TGC Video tutorials
These videos will give you an all round guide of the principles of DBPRO programming. It's nice to watch a video instead of reading sometimes; but if you prefer reading, the next few tutorials are good reads.
TDK Beginner's tutorials
Sadly the most important tutorial is the boring one. Skip this tutorial and you will likely perform 'spaghetti programming'; 1000s of instructions too messy to read. You can't make a game that you can't understand; you can't get much help from people who can't understand your code.
What you code today gets forgotten tomorrow. This tutorial covers HOW TO PROGRAM IN DBPRO, and HOW NOT TO PROGRAM IN DBPRO. It's a bit like an elementary school of programming, but most of the programming you end up doing, the 10s of 1000s of lines of code will need to be structured the way that is recommend here; the way that is organized.
I cannot stress enough how important tidiness is when an average day in programming life is spent looking for needles in haystacks; finding faults as small as a missing word in a 70 thousand, 80 thousand line program with over 500,000 - 600,000 words really requires a neat and tidy layout to navigate. It's all fine locating things during the first 5,000 to 10,000 lines, but things start to get really complex when you reach the 20s; and compile times take longer and longer.
You should also seperate your code into classes stored in seperate project files. Your project folders and files are like road maps to things in your project. Comments; remarks, these are like road signs. The
Indigo IDE features a nice To-Do list and snippet system that makes organization more easier.
Arrays, by Sixty Squares
80-90% of your logical game data in memory will reside in arrays. You need to use them to relate information to indexes so that, dynamic information, stuff created while the game runs, can be tracked, copied, saved and manipulated. Consider that each car, player and checkpoint will need an array element of a given number which contains their information; a bit like an article number in a database. UDTs stand for user defined types, think of these as database fields, and arrays as database tables.
Diggseys 3D Math tutorials
You do not need to understand everything about trigonometry to make a video game, and need not understand matrices and interpolation straight off the bat, but you will need to at least know how to use vectors; particularly in driving games, otherwise you will end up doing more work than is necessary using singular numeric vehicle velocity elements and will struggle to make use of physics engines later on. Be amazed at how many vectors you need just to make an car drive like a car!
My tutorial about memblocks
This is my tutorial that features picture illustrations of how memblocks work. This is good learning because memblocks will be oblivious at first when you learn; its that section of the documentation that seems to make no sense at first. But later on it hits you that you will need to understand how they work to do anything complex that cannot be done with Arrays. It is also a way of learning how to use Memory Banks, and this is all a stepping stone for getting into direct memory access.
Also, watch Blender and Photoshop/Gimp tutorials during your spare time. Watch things like these, not X Factor.
Real good Blender beginner tutorial videos
C: This can be done while learning the basics. Watch lots of driving games, lots of real televised racing events and get a good grasp of driving physics; no point making something that racing fans will look at as a poor simulation.
Take notes of how the camera moves, how things sound and look in the game.
Nothing beats watching and listening to the real thing.
Bit of a rally
Madness!
D: PHYSX is NVidia's hardware/software accelerated collision, motion and joints simulator, and I recommend buying a copy of Dark Dynamix as a foundation for your vehicle engine. Dark Physics alternative vehicle engine is not a vehicle engine in my opinion, it is a hidden rolling sphere with a hull floating on it; something happened when it was created, somebody didn't notice how bad it was. Dark Dynamix is the best plugin DBPRO has for racing games period; I've used them all. In Dark Dynamix, you work with the wheels and chassis as separate logical entities, after-all, they are separate things in real life.
But vehicles is not the only thing you need this for; it's also good for particles effects, rocks and other physical objects that move around.
E:Install these FREE plugins, I've explained why:
Collision
Sparkys Collision is a replacement for the collision system that comes with DBPRO. You will need this for logical and functional collision purposes.
Utilities
Matrix1, this is an upgrade for DBPRO's core library. Of particular interest here in relation to creating a great driving experience, is its 3D maths commands; for instance binding object positions and rotations to vectors; and its function pointers feature, so you can bind function calls to things like keystrokes/joypad buttons or checkpoint collisions in an organized fashion.
Read the help files!
You should scan through the help files for all the commands, they are there to help you; and will teach you great techniques. Some gems include time tickers, INI file lookups, render targets, limb creation and array pointers.
For HUD Display
Advanced2D is an upgrade to the 2D drawing library that does not slow down your game as much. The traditional 2D commands are not suitable for fast simulations; not that the person who created DBPRO, used it to build FPS Creator, which is a type of game engine that does not need much 2D drawing; a racing game needs lots of 2D visual indicators; you will need Advanced2D.
Windows Controls
BBB GUI is one of the only good ways for DBPRO to create windows controls. You will need windows controls to build your tweaking tools; any other method will require too much work. Windows supplies many controls so you can save time.
XML Game Data
XML Plugin by MadBit is quite a young plugin that packs power. It's the best XML plugin for DBPRO, and XML is the best configuration file format in the world; because it is extensible and tool programs and services can interpret it more easily than binary files. For security, any file format can be encrypted. Use XML to create your configuration files so you can alter the behavour of the program without having to recompile. Things like car names, track descriptions, text, key button bindings belong in configuration files, not in constants; these types of information need to change often.
Particles
This particles plugin is a good addition for your work; you could use it to create the skidding particles and exhaust smoke. The particle engine that comes with Dark Basic is limited, and sometimes crashes.
F: Observe these coding examples; Use these kinds of snippets to learn how to tackle common issues.
Collision demo (using sparkys collision)
set display mode 800,600,32
sync on
sync rate 0
hide mouse
randomize timer()
make object cylinder 1,10
color object 1,rgb(200,0,0)
autocam off
position camera 0,0,-30
`SC_setupComplexObject 1,0,2
rem or
SC_setupObject 1,0,0
`make a bullet marker
make object plain 501,2,2
color object 501,rgb(255,255,255)
hide object 501
rem make a white image, since coloring doesn't work very well with no light
makeColorImage(1,1,rgb(255,255,255))
texture object 501,1
set object light 501,0
do
yrotate camera camera angle y()+(mousemovex()/10.0)
xrotate camera camera angle x()+(mousemovey()/10.0)
position mouse 400,300
rem spacebar for rotation
if spacekey()=1 and rotatetimer+300<timer()
rotatetimer = timer()
rotate object 1,rnd(359),rnd(359),rnd(359)
rem updates the object, including scaling if allowed.
SC_updateObject 1
endif
hide object 501
if mouseclick()=1
rem get our simple collision vector
oldx#=camera position x()
oldy#=camera position y()
oldz#=camera position z()
move camera 200
x#=camera position x()
y#=camera position y()
z#=camera position z()
move camera -200
collide=SC_rayCast(0,oldx#,oldy#,oldz#,x#,y#,z#,0)
if collide>0
rem get the collision point
newx#=SC_getStaticCollisionX()
newy#=SC_getStaticCollisionY()
newz#=SC_getStaticCollisionZ()
rem get collision normal
normx#=SC_getCollisionNormalX()
normy#=SC_getCollisionNormalY()
normz#=SC_getCollisionNormalZ()
rem position and point a marker in the right direction
position object 501,newx#+normx#/100.0,newy#+normy#/100.0,newz#+normz#/100.0
point object 501,newx#+normx#,newy#+normy#,newz#+normz#
show object 501
endif
endif
text 0,0,\"Move mouse to aim, left click to shoot\"
text 0,20,\"Press space to randomly rotate object.\"
text 0,60,str$(screen fps())
text 0,80,str$(collide)
ink rgb(255,0,0),0
circle 400,300,10
dot 400,300
ink rgb(255,255,255),0
sync
loop
end
function makeColorImage(image,mem,color)
make memblock mem,16
write memblock dword mem,0,1
write memblock dword mem,4,1
write memblock dword mem,8,32
write memblock dword mem,12,color
make image from memblock image,mem
delete memblock mem
endfunction
Quote: "I'd recommend searching for a vehicle physics demo, and altering that."
Here is a simple demo
Vehicle demo (using Dark Dynamix)
Rem Project: Vehicle
Rem Created: Monday, February 27, 2012
Rem ***** Main Source File *****
//-- Be sure to add \"PhysX Constants.dba\" to your solution.
global ground = 1
global hull = 2
global wheel1 = 3
global wheel2 = 4
global wheel3 = 5
global wheel4 = 6
sync on
sync rate 60
autocam off
color backdrop rgb(200, 200, 255)
//-- Physics
DYN START
DYN SET GRAVITY 0, -9.8, 0
DYN MAKE GROUND PLANE
DYN SET PARAMETER NX_VISUALIZATION_SCALE, 1.0
DYN SET PARAMETER NX_VISUALIZE_COLLISION_SHAPES, 1.0
//-- Ground
make object plane ground, 1000, 1000
rotate object ground, -90, 0, 0
//-- Initial vehicle height
vHeight# = 5.0
//-- Make Vehicls Hull
make object box hull, 5, 1, 10
position object hull, 0, vHeight#, 0
//-- Make Wheels From Cylinders -- you would laod in your wheel model here
make object cylinder wheel1, 2
make object cylinder wheel2, 2
make object cylinder wheel3, 2
make object cylinder wheel4, 2
// Make our objects pretty colours.
color object ground, rgb(255, 100, 100)
color object hull, rgb(100, 100, 255)
color object wheel1, rgb(100, 255, 100)
color object wheel2, rgb(100, 255, 100)
color object wheel3, rgb(100, 255, 100)
color object wheel4, rgb(100, 255, 100)
//--NOTE: Try to be sure the wheel model is setup so when loaded it would travel
//--along the z axis. The cylinder shape is not setup like this so we need to do
//--the following.
//--I only partly understand why this works, I'm just happy it does:)
//--Rotate Cylinders
rotate object wheel1, 0, 0, 90
rotate object wheel2, 0, 0, 90
rotate object wheel3, 0, 0, 90
rotate object wheel4, 0, 0, 90
//--Fix Pivot
fix object pivot wheel1
fix object Pivot wheel2
fix object pivot wheel3
fix object pivot wheel4
//--Rotate back
rotate object wheel1, 0, 0, -90
rotate object wheel2, 0, 0, -90
rotate object wheel3, 0, 0, -90
rotate object wheel4, 0, 0, -90
//--Position Wheel
position object wheel1, 4, vHeight#, 5
position object wheel2, -4, vHeight#, 5
position object wheel3, 4, vHeight#, -5
position object wheel4, -4, vHeight#, -5
//--Make Hull
DYN MAKE BOX hull, 10.0
//--Make Wheels
DYN MAKE WHEEL wheel1, 10
DYN MAKE WHEEL wheel2, 10
DYN MAKE WHEEL wheel3, 10
DYN MAKE WHEEL wheel4, 10
//--Create Fixed Joint Descriptor
DYN MAKE JOINT DESC 1
DYN JOINT DESC SET MOTION X 1, 0
DYN JOINT DESC SET MOTION Y 1, 0
DYN JOINT DESC SET MOTION Z 1, 0
DYN JOINT DESC SET SWING1 MOTION 1, 0
DYN JOINT DESC SET SWING2 MOTION 1, 0
DYN JOINT DESC SET TWIST MOTION 1, 0
//--Attach Wheels to Body
//--wheel1
DYN JOINT DESC SET ACTOR A 1, hull
DYN JOINT DESC SET ACTOR B 1, wheel1
DYN JOINT DESC SET GLOBAL ANCHOR 1, 0, 0, 0
DYN MAKE JOINT 1, 1
//--wheel2
DYN JOINT DESC SET ACTOR B 1, wheel2
DYN JOINT DESC SET GLOBAL ANCHOR 1, 0, 0, 0
DYN MAKE JOINT 2, 1
//--wheel3
DYN JOINT DESC SET ACTOR B 1, wheel3
DYN JOINT DESC SET GLOBAL ANCHOR 1, 0, 0, 0
DYN MAKE JOINT 3, 1
//--wheel4
DYN JOINT DESC SET ACTOR B 1, wheel4
DYN JOINT DESC SET GLOBAL ANCHOR 1, 0, 0, 0
DYN MAKE JOINT 4, 1
//--ADVANCED, very brief introduction to the more advanced controls you
//--have over your wheel shapes. See documentation for more details
//--about the 'tire force function'.
DYN MAKE TIRE FUNC DESC 1
DYN TIRE FUNC DESC SET STIFFNESS FACTOR 1, 1000 //1000 = Very low friction, default 1000000 = High friction
//--Lateral Slide(back wheels)
DYN WHEEL SET LAT TIRE FORCE FUNC wheel3, 0, 1
DYN WHEEL SET LAT TIRE FORCE FUNC wheel4, 0, 1
//--Longitudal Spin(back wheels)
//DYN WHEEL SET LONG TIRE FORCE FUNC wheel3, 0, 1
//DYN WHEEL SET LONG TIRE FORCE FUNC wheel4, 0, 1
DYN SIMULATE
do
DYN FETCH RESULTS
DYN UPDATE
DYN WHEEL UPDATE wheel1, 0
DYN WHEEL UPDATE wheel2, 0
DYN WHEEL UPDATE wheel3, 0
DYN WHEEL UPDATE wheel4, 0
DYN DEBUG RENDER
processUserInput()
//...
DYN SIMULATE
position camera 0, 50, -50
point camera object position x(hull), object position y(hull), object position z(hull)
sync
loop
function processUserInput()
torque# = 0.0
steer# = 0.0
if upkey()
DYN ADD LOCAL FORCE hull, 0, 0, 10 `Wakes up actor if asleep, wheels will not do this.
torque# = 100
endif
if downkey()
torque# = -100
endif
if leftkey()
steer# = -20
endif
if rightkey()
steer# = 20
endif
DYN WHEEL SET MOTOR TORQUE wheel3, 0, torque#
DYN WHEEL SET MOTOR TORQUE wheel4, 0, torque#
DYN WHEEL SET STEER ANGLE wheel1, 0, steer#
DYN WHEEL SET STEER ANGLE wheel2, 0, steer#
endfunction
There are other general useful snippets at the
code corner and code snippets section
G: Search the forum for tips on time based movement, performance and efficiency. Learn how to use timers; learn how to be efficient with CPU/GPU usage. Time your events, don't run a constant loop if you can help it.
F: Learn about boolean operators. These work like circuit boards that determine if something is true or false. These are the building blocks of logic, and is the means to creating smart applications.
There is a help page in the documentation, plus I have created an article about it towards the boolean flags section. Visit it by clicking the image.
If you get this far you will be driving in your car game; but this is just the beginning. You will also want to look into map development and shaders at some point, but these are another huge topics.
For now check out
TurboSquid for free or cheap 3D models.
Good luck!