This guide will take you step-by-step through the process of creating and running a new Torque 3D project utilizing the BaseGame template.
Table of Contents
|
Setup
To start, you'll want to get your project through the initial CMake configuration, to after you input the App's name. If you're unfamiliar with the initial setup steps, feel free to refer to to the compiling-in-windows article(or Linux as applicable) and walk through the first few steps and put in the Torque_App_Name and hit configure. Once it's done, you'll see a screen like this:
Change the TORQUE_TEMPLATE field to BaseGame and generate. Then open the project solution and compile with the INSTALL project as usual. If you then check your My Games/<App_Name>/game dir, it will look like this:
As you can see, there are some differences to the old Full and Empty templates.
But before we dive into the directory structure, lets fire up our application and see what we have.
As we can see, there's a default UI, complete with main menu, options menu, etc. Fell free to take a few moments to poke through the interface and we can continue when you're ready.
Walkthrough Tour
Closing out the application, now we'll turn our attention to the folder layout.
Core Directory
Lets start with the core directory. Opening it up shows this:
So to start, "What is the core folder for?". The answer is "This is everything needed to initialize the engine and display a window - with a few common utility bits of functionality as well.
So, for a quick breakdown, you have:
- console (This is for the command console window)
- fonts (This contains font files)
- gfxData (This contains some common shader and material definitions for core classes, such as terrain, water, etc)
- gfxprofile (Can contain some custom configuration rules for given API and graphics card combos)
- images (A few common images)
- lighting (All the shader and material data for the lighting models)
- advanced (Stuff for the advanced, deferred lighting)
- basic (Stuff for the forward renderer)
- shadowmaps (Init for the shadowmaps)
- postFX (All the data for the core, common PostEffects such as HDR, SSAO, FXAA, etc)
- sfx (Default data and setup for audio emitters and soundspaces)
- shaders (All the common core shaders used for rendering things)
You'll also note some script files right in the root of the directory, which do other setup of various main systems, such as the audio system, canvas/window, render manager, etc. We'll go into the path the initalization of the engine takes later.
Data Directory
Moving on, lets go open the data directory. Inside, we'll find:
- clientServer
- shaderCache
- ui
As well as a defaults script file and our splash and icon images.
These folders are Modules. They are packages with convenient asset management handling, and easy-to-drop-in-and-out structure. For a more in-depth look of how modules work, check the article here: Modules
clientServer Module
If you open the clientServer folder, you'll find the common setup for modules. Various sub-folders for organization, and the module's module definition *.module file, and the module's initialization script file.
If we open up the *.module file, we'll see what the module definition looks like:
<ModuleDefinition ModuleId="ClientServer" VersionId="1" Description="Default module for the game." ScriptFile="ClientServer.cs" CreateFunction="create" DestroyFunction="destroy" Group="Game"> </ModuleDefinition>
The modules article linked above will go into the in-depth guts of the module file, but at minimum, we can see in here that we have our unique module name as the ModuleID, the version number, a description, what our initialization script file is named, what the create and destroy functions in said initialization file are called, and what module group it's in.
A look into the script file looks like this:
// The general flow of a gane - server's creation, loading and hosting clients, and then destruction is as follows: // First, a client will always create a server in the event that they want to host a single player // game. Torque3D treats even single player connections as a soft multiplayer game, with some stuff // in the networking short-circuited to sidestep around lag and packet transmission times. // initServer() is called, loading the default server scripts. // After that, if this is a dedicated server session, initDedicated() is called, otherwise initClient is called // to prep a playable client session. // When a local game is started - a listen server - via calling StartGame() a server is created and then the client is // connected to it via createAndConnectToLocalServer(). function ClientServer::create( %this ) { echo("\n--------- Initializing Directory: scripts ---------"); exec( "./scripts/client/client.cs" ); exec( "./scripts/server/server.cs" ); $Game::MissionGroup = "MissionGroup"; initServer(); %dbList = new ArrayObject(DatablockFilesList); // Start up in either client, or dedicated server mode if ($Server::Dedicated) { initDedicated(); } else { initClient(); } } function ClientServer::destroy( %this ) { // Ensure that we are disconnected and/or the server is destroyed. // This prevents crashes due to the SceneGraph being deleted before // the objects it contains. if ($Server::Dedicated) destroyServer(); else disconnect(); // Destroy the physics plugin. physicsDestroy(); sfxShutdown(); echo("Exporting client prefs"); %prefPath = getPrefpath(); export("$pref::*", %prefPath @ "/clientPrefs.cs", false); echo("Exporting server prefs"); export("$Pref::Server::*", %prefPath @ "/serverPrefs.cs", false); BanList::Export(%prefPath @ "/banlist.cs"); } //----------------------------------------------------------------------------- function StartGame( %mission, %hostingType ) { if( %mission $= "" ) { %id = CL_levelList.getSelectedId(); %mission = getField(CL_levelList.getRowTextById(%id), 1); //error("Cannot start a level with no level selected!"); } if (%hostingType !$= "") { %serverType = %hostingType; } else { if ($pref::HostMultiPlayer) %serverType = "MultiPlayer"; else %serverType = "SinglePlayer"; } // Show the loading screen immediately. if ( isObject( LoadingGui ) ) { Canvas.setContent("LoadingGui"); LoadingProgress.setValue(1); LoadingProgressTxt.setValue("LOADING MISSION FILE"); Canvas.repaint(); } createAndConnectToLocalServer( %serverType, %mission ); } function JoinGame( %serverIndex ) { // The server info index is stored in the row along with the // rest of displayed info. if( setServerInfo( %serverIndex ) ) { Canvas.setContent("LoadingGui"); LoadingProgress.setValue(1); LoadingProgressTxt.setValue("WAITING FOR SERVER"); Canvas.repaint(); %conn = new GameConnection(ServerConnection); %conn.setConnectArgs($pref::Player::Name); %conn.setJoinPassword($Client::Password); %conn.connect($ServerInfo::Address); } }
As you can probably guess, this does all the frontline initialization of the client/server stuff for Torque3D. It used to be spread out all over the place in the old Empty and Full modules, but it's all consolidated in this module now. The advantages of this are:
- easiler to track down and change stuff for your game - especially if you wish to keep your changes for later projects, you can just keep the module and reuse it without needing to port your changes to the scripts manually each time, and
- If you want to do a completely different system, such as purely singleplayer and sidestep all the level transmission and sending of data to the client, you can remove the module, write a new, lighter one that does that, and skip out a lot of work ripping the system you don't need out.
A quick look shows that the Create() function does some initialization work based on if it's a dedicated server, or a client/server. It also sets up our DatablockFilesList, which lets other modules store what datablocks will be sent off to clients when they connect.
The Destroy function likewise shuts everything down and saves out any relevant preferences.
The 2 other common functions are StartGame, which, unsurprisingly, starts a game, and JoinGame, which lets a client connect to a externally hosted game.
ShaderCache folder
This is just simply where the procedurally generated shader files for materials are cached to by default. It's exactly the same as the Full/Empty template's shaders/procedural directory.