Alright everyone!
With 3.10 done, we've started moving towards all the big and great things for 4.0, and the first biggie on the list is finalizing and rolling in the new template arrangement.
The current, near-final branch is here:
https://github.com/areloch/Torque3d/tree/NewBaseGameTemplateFinalSome changes since the last time I had everyone eyeballing this: obviously it's been updated to comply with 3.10, but the shaders and postFX stuff has been moved to /core/, and the visualizer shaders were moved to the tools directory.
I also fixed up the editor launch, so that if no levels are found because no modules have any that hook back to the default choose level dialog, you'll get a pop-up prompt to load the default editor blank level. If you're not already in a running game, launching the editor from the keybind(F11) or the main menu option will do the same, just open the default blank level. It'll also create a camera object and push an editor-specific movemap, so even if you have nothing other than a window spawning, you should be able the launch the editor and get making stuff.
Also moved the grid materials and a blank skybox material into the tools dir so the editor always has at least a few materials to work with.
So, I know there's been some inquiries in how the general behavior will work with modules and all that in relation to the new template, so I'll do a breakdown post and explain the flow of the new template here, and how it'll be expanded on in the future.
So, for the moment, the new BaseGame template will exist alongside the current Empty and Full templates, and the Full template will stay the default picked template by cmake, just so we can be sure no big problems were missed before we make the sucker the mainstay and fully deprecate the old templates.
So the first thing to do is select it as your targeted template in cmake:

Then build and install as per the norm.
If you fire it up, you'll get the default-as-included ui, all snazzy and modern-like:

Options menu behaves as you'd expect, as does the Join Server and exit buttons, and the launch world/gui editor buttons likewise behave how you'd expect.
If you click Singleplayer or Create Server buttons, however, you'll be met with a mostly blank screen, and a pop-up prompt informing there are no found levels.

If we take a look at our game's directory, we can figure out why there'd be no levels. Here's our root directory:

Core obviously has all our 'stuff needed for the engine to actually initialize and run' and tools is the editor, so we'll ignore those for now. So if we open the data folder we see this:

Here, we have the only two default modules included with the template currently - the clientServer guts, which enables you to play singleplayer or host multiplayer servers, and all the level-loading code associated with letting clients join said server. This is basically the default functionality of the Empty/Full templates in regards to launching a game.
There's also the UI folder, which has the default modern-dark UI we were looking at a minute ago.
These are
MODULES, which I'd talked about in my workblog a fair bit. But we have no gameplay modules currently. The plan is for the new Project Manager to track and allow easy un/installation of modules, but until that's ready, we'll just stick with copying the ones we care about for now. If we go back to our <engine directory>/Templates folder, we'll find a Modules folder inside:

Opening that up will reveal 3 module folders: BlankGame, FPSGameplay, and spectatorGameplay.
Blank game is designed as the ultimate bare-bones project starter. It hard-loads a level created via script, and shortcuts the client/server connection stuff, so it's basically 'real' single player in that there's no true hosted server and distinct client(at least as far as T3D is concerned. Obviously it has those aspects in the backend of the engine, but you don't truely 'connect' in the same way the clientServer module sets it up as. You basically bypass all that for a local-only connection)
Then it dumps you in that map with a camera and that's it. It's up to you to go from there and work on everything, UI, gameplay, etc. Most people probably won't want to start with this one. Pretty much bypasses the clientServer and UI modules.
FPSGameplay basically replicates the Full template's aspects. It has the art assets, gameplay/weapon scripts and the levels. So the empty room, empty terrain and outpost missions, the various guns and mines, the vehicles, all that jazz. If you're working on an FPS, this is a decent starting place.
spectatorGameplay is basically the Empty Template. Empty room mission and a controllable spectator camera and not much else. A good middleground template, where you don't need all the stuff in the FPSGameplay template, but want it to hook into the UI and clientServer module functionality like the FPSGameplay module
Hook into the UI and clientServer module functionality, you say?Indeed I did, we'll get to that momentarily. So once you have your gameplay module of choice, copy the entire module's folder and drop it into your project's data folder, alongside the ui and clientServer module folders. In our case, that means we'd now have a data/FPSGameplay folder alongside the clientServer folder and ui folder.
If you fire the game back up, and click Singleplayer or Create Server, you'll see that we now have some levels listed!

That's using the FPSGameplay module, of course.
And, picking a level and launching the game(letting the models cache, of course), you'll find you have the working guts of an FPS(or ghost simulator, in the case of the spectatorGameplay module)!
Gee willikers, is that what you were saying about hooking into the other modules?Curiously dated proclamations of excitement aside, yes that's what was being referred to!
So lets crack open the FPSGameplay module folder and have an eyeball at what's going on with it to make it all work.

Looks pretty run of the mill other than the auspiciously named FPSGameplay.cs and FPSGameplay.module
If we open them up, here's what we'll see:
// 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 FPSGameplay::create( %this )
{
//server scripts
exec("./scripts/server/aiPlayer.cs");
exec("./scripts/server/camera.cs");
exec("./scripts/server/chat.cs");
exec("./scripts/server/cheetah.cs");
exec("./scripts/server/commands.cs");
exec("./scripts/server/deathMatchGame.cs");
exec("./scripts/server/health.cs");
exec("./scripts/server/inventory.cs");
exec("./scripts/server/item.cs");
exec("./scripts/server/player.cs");
exec("./scripts/server/projectile.cs");
exec("./scripts/server/proximityMine.cs");
exec("./scripts/server/radiusDamage.cs");
exec("./scripts/server/shapeBase.cs");
exec("./scripts/server/spawn.cs");
exec("./scripts/server/teleporter.cs");
exec("./scripts/server/triggers.cs");
exec("./scripts/server/turret.cs");
exec("./scripts/server/vehicle.cs");
exec("./scripts/server/vehicleWheeled.cs");
exec("./scripts/server/VolumetricFog.cs");
exec("./scripts/server/weapon.cs");
//add DBs
if(isObject(DatablockFilesList))
{
for( %file = findFirstFile( "data/FPSGameplay/scripts/datablocks/*.cs.dso" );
%file !$= "";
%file = findNextFile( "data/FPSGameplay/scripts/datablocks/*.cs.dso" ))
{
// Only execute, if we don't have the source file.
%csFileName = getSubStr( %file, 0, strlen( %file ) - 4 );
if( !isFile( %csFileName ) )
DatablockFilesList.add(%csFileName);
}
// Load all source material files.
for( %file = findFirstFile( "data/FPSGameplay/scripts/datablocks/*.cs" );
%file !$= "";
%file = findNextFile( "data/FPSGameplay/scripts/datablocks/*.cs" ))
{
DatablockFilesList.add(%file);
}
}
if(isObject(LevelFilesList))
{
for( %file = findFirstFile( "data/FPSGameplay/levels/*.mis" );
%file !$= "";
%file = findNextFile( "data/FPSGameplay/levels/*.mis" ))
{
LevelFilesList.add(%file);
}
}
if (!$Server::Dedicated)
{
exec("data/FPSGameplay/scripts/client/gameProfiles.cs");
//client scripts
$KeybindPath = "data/FPSGameplay/scripts/client/default.keybinds.cs";
exec($KeybindPath);
%prefPath = getPrefpath();
if(isFile(%prefPath @ "/keybinds.cs"))
exec(%prefPath @ "/keybinds.cs");
exec("data/FPSGameplay/scripts/client/inputCommands.cs");
//guis
exec("./scripts/gui/chatHud.gui");
exec("./scripts/gui/playerList.gui");
exec("./scripts/gui/playGui.gui");
exec("./scripts/gui/playGui.cs");
exec("data/FPSGameplay/scripts/client/message.cs");
exec("data/FPSGameplay/scripts/client/chatHud.cs");
exec("data/FPSGameplay/scripts/client/clientCommands.cs");
exec("data/FPSGameplay/scripts/client/messageHud.cs");
exec("data/FPSGameplay/scripts/client/playerList.cs");
}
}
function FPSGameplay::destroy( %this )
{
}
for the script file,
and
<ModuleDefinition
ModuleId="FPSGameplay"
VersionId="1"
Description="Starter module for FPS gameplay."
ScriptFile="FPSGameplay.cs"
CreateFunction="create"
DestroyFunction="destroy"
Group="Game"
Dependencies="clientServer=1,UI=1">
</ModuleDefinition>
for the module file.