• entries
    24
  • comments
    59
  • views
    16,242

About this blog

A blog where I talk about anything relating to Leadwerks, and then some.

Entries in this blog

reepblue

Luawerks has been updated this morning, making the console more responsive and a new tab for the Options Menu for user's to bind keys to actions.

Actions have always been part of Luawerks, but until now, there wasn't really a motive to use them. Now, the Action class look in the config to check what key the user binded to that action. You can read more on how this works here. Like the console, this may be improved more in the future. 

 

About Luawerks

Luawerks is a Lua framework for video games developed on the Leadwerks Game Engine. It supplies developers with additional functions, handles the game loop and allows them to debug their code with a developers console. With all that out of the way, you can focus on making your game fun!

You can purchase Luawerks from the Leadwerks Workshop Store for $9.99.

For documentation and bug reporting, please visit the GitHub page.

luawerksgui2.JPG

reepblue

0A7625F01AC8903577882B9E223032CF33CA6CFB

Luawerks has been updated for Leadwerks 4.4, taking advantage of the new GUI system while adding new features and commands that allow you to develop your game better.

 

Developer Console Refresh

The Developer Console is the stable of the framework. Thanks to the GUI, you can now scroll through your history, highlight, and move the cursor around! Page through your history using the Page Up and Page Down keys! Having a console is vital for development as it allows developers to change maps and other values in-game instead of restarting the program after changing some code. You can add your own commands easily as well. For more information, see the page about the Console here.

baf5c7c590.JPG

 

An Integrated Menu

The standard release of Leadwerks 4.4 comes with a menu. I shipped my own standard menu with Luawerks to be more integrated with the rest of the framework. Unlike the official menu script, the Luawerks menu uses 2 GUI's; one for the main menu, and the other for the panels/windows. You can just edit the main menu without effecting the panels, and vise versa. Menu also calls the panels via console commands. 

af2cf57b25.JPG

 

The Gotcha's Fixed

Upon installing Luawerks into the project, I recommended that the user calls SetCamera() instead of Camera:Create(), so that the world class would know what camera to reference. This caused a problem when the user switched maps, so I also requested that the user releases the camera too. I replaced this with a for loop in the GetCamera() function, and calling camera:Release() isn't necessary.

You can now load maps in-which their names have spaces! 

 

Load Models as Copies

I added a second parameter to the LoadModel() function. If set to true, the function will load a model, create and return a copy of the model, and release the original asset. This allows you to manipulate that model without effecting other references. This is great if you want one model to use multiple skins.

This image shows two of the same models loading two different materials.

311dd769fe.png

 

Here is an example on how to create a copied/unique model:

self.mymodel = LoadModel("Models/MyModel.mdl",true)

 

LOD Models [Experimental]

An experimental feature I've added is an object with multiple models and it switches the models based on the camera's distance from the entity. This only works on Static objects as I didn't calculate velocity and mass.

You'd need to make it an object script like so:

function Script:Start()
	self.model = ModelLOD("Models/LodTest/main.mdl")
	self.model:Get():SetPosition(self.entity:GetPosition())
	self.model:AddLOD("Models/LodTest/lod1.mdl",5)
	self.model:AddLOD("Models/LodTest/lod2.mdl",10)
	self.model:AddLOD("Models/LodTest/lod3.mdl",15)
end

function Script:UpdateWorld()
	self.model:Update()
end

As I said before, this was something I was playing with, and I don't think it's ready for full use yet. Although it'll help with poly counts, each ModelLOD needs to be updated to get the distance of the camera, so you'd need to weigh your costs.

On top of all that, bug fixes were made, new commands were added, and more things are planned for future releases. Documentation will continue to be updated here.

 

About Luawerks

Luawerks is a Lua framework for video games developed on the Leadwerks Game Engine. It supplies developers with additional functions, handles the game loop and allows them to debug their code with a developers console. With all that out of the way, you can focus on making your game fun!

You can purchase Luawerks from the Leadwerks Workshop Store for $9.99.

For documentation and bug reporting, please visit the GitHub page.

reepblue

After I've returned from Steam Dev Days, I caught a terrible cold, so my first week home was unproductive when it came to LEX or Blue Portals. But besides that, I had a great time! I mentioned briefly in my last blog post before I went that I was giving LEX some reorganizing and defragmenting. This blog post, I'm going to go more into detail.

 

LEX2 has a lot of things going for it. The developer console is really handy, the AssetManager prevents crashes and has the ability to pre-loads things for you and the PostStart() command for entities allows you to make entities do things RIGHT AFTER the map loads instead of during the loading process. All very helpful!

 

Crawler's Den taught me a lot about what I was doing with LEX2, and where I should go. I designed it to be more Lua friendly than the initial release. but also allowed easy C++ classes to be made. Crawler's Den had the challenge of "Make a whole game in Leadwerks using nothing but C++". I know it was do-able, but how hard could it be?

 

Leadwerks today isn't really as optimized to be developed using C++ as it is to Lua. I had to do go through a lot of hoops with somethings that could have been done easily if I just wrote the game in Lua. For instance, making C++ classes required more thought, and to attach my C++ puppeteers (actors) to entities in the editor, I had to make a Lua script that acted like a Hammer fgd file to sync it's keyvalues, inputs and outputs. Oh and on top of that, I had to make sure that each puppeteer got deleted properly. All and all, it was do-able, just not ideal at all!

 

I'm switching back to be more focused to making games with Lua for now. I started by making a new project and re-writing the console system to be more flexible. Instead of defining all ConCommands in one cpp file, ConCommands can be defined anywhere now like:

 


static void ConCommand_SayHi(vector parameters)

{

System::Print("Hi")

}

 

static ConCommand sayhi("sayhi", ConCommand_SayHi);

 

With this system, it may be possible to make your own console commands via lua, but I'd have to look into it.

 

My ExSystem Class is derived from Leadwerks System Class, and it's how to talk to the application directly. It handles the dev console, pausing, resuming, and other states that the application might be in. 90% of ExSystem can be called from Lua.

 

The Developer console is much more powerful than it ever was. You can now make entities fire script functions or outputs by the entity name, or using !picker when looking at it.

 

fire <entityname> <functionname>

 

There are also a lot of Utility functions from the previous codebase. One of my favorites is this function.

 

inline Leadwerks::Entity* UTIL_PickFromCamera(int pDistance, int pCollisionType=0, float pRadius=0)

{

Leadwerks::PickInfo pickinfo = Leadwerks::PickInfo();

Leadwerks::Vec3 p0 = UTIL_GetActiveCamera()->GetPosition(true);

Leadwerks::Vec3 p1 = Leadwerks::Transform::Point(0, 0, pDistance, UTIL_GetActiveCamera(), NULL);

if (UTIL_GetActiveCamera()->world->Pick(p0, p1, pickinfo, pRadius, false, pCollisionType))

{

return pickinfo.entity;

}

 

return nullptr;

}

 

I also made the settings.config file store in the AppData folder instead of the game's root. While I never had any permission issues with the old way, still best to have the user's settings there.

 

I merged both the WindowManager and ContextManager to be one class; There is just a WindowManager now. There was no point to have the context be managed in it's own class; definitely now since I took out my UI code I had in there for the console drawing. I also fixed Screenshots being properly placed in it's own Directory in the game's folder!

 

The World Manager is what got the most fat reduced. Before I had a great chunk of code that was ether commented or ifdef'd out. For example, I had old code for my cubemap factory before the Probes where a thing, and other checks that in the long run might cause more problems later. The World Manager is responsible that when a user want's to load a map, a world get's created or cleared, and PostStart is fired on all entities if they have a script. If the user want's to go back to the menu, the world manager clears, and then releases the world. Something that was 913 lines got reduced to 260, and it does pretty much the exact same thing.

 

I removed the InputManager as at Dev Days I learned that that Steam will later be able to handle that for you, not exclusive to the Steam Controller. Also, the implementation was really confusing and tricky.

 

Finally, I removed a bunch of classes that are no longer needed including the Puppeteer class as the focus is now Lua. I want to keep the scope of things small right now. All you need to convert a game using the standard executables to the LEX is to replace the 2 executables and add this self explanatory Lua script that'll override main.lua.

 

--This function will be called once when the program starts
function App:Start()
return true
end
--This function will be called right after when the program starts.
function App:PostStart()
end
--This is our main program loop and will be called continuously until the program ends
function App:Loop()
return true
end
--This function is called once when the program pauses time.
function App:onpause()
end
--This function is called once when the program resumes time.
function App:onresume()
end
--This function is called while the program is loading a map. (This is where you draw your loading screen!)
function App:OnMapLoad()
end
--This function is called when the program finished loading a map.
function App:OnPostMapLoad()
end
--This function is called when the program disconnected from a map.
function App:OnDisconnect()
end
--This function is called when the program closes.
function App:OnShutdown()
end

 

Since it's really those three files that need to be shipped for the product to work, I can use the the standard Leadwerks Project Manager again. I don't plan on releasing the source code at this time. Maybe when making C++ games becomes more streamlined I'll re-integrate my C++ systems.

 

There are still somethings to do though:

  1. Integrate the dev console to the Leadwerks GUI when that's fully done. The CMD using Cin approach that I'm using now is kind of bad.
  2. Play with the app a few hours a day, fix bugs, build on it a little each week.
  3. Find a good method in distribution, and keeping people up to date.

 

In the future, I also hope to add more classes you can use while making gameplay objects. Somethings like a Beam class, and such to make things much more simpler.

 

I also hacked together this shader that takes in roughness and ao sheets along with the diffuse, normal and spec. My artist gave me some textures right from Mamoset and my goal was to import them to Leadwerks as close as I could. I think they came out really well.

 

roughnessao.png

reepblue

Quick Update

Very happy on how everything is coming along. Blue Portals: Anniversary Edition development is going a tad slower than I wanted it too, but it's coming along nicely. We've finally shipped that

in late August, and the mod made even more progress since. We just got some unknowns to work out like voice acting and music. I got some puzzles in the pipeline, and the mod right now has 11 playable maps.

 

LEX2 is getting re-organized. I went back to the CMD window based dev console as I plan on adding in the final console with the new GUI once that's done and well documented. I also implemented a Convar system along with a new conommand system. Pretty much, a new foundation is in place, and I shifted my focus to be easier lua development for now. I'll write about it more when I know more on how I wish to accomplish this.

 

Steam Dev Days is next week! I've spent the last month going through my archive of experiments and prototypes, along with making demo maps for Blue Portals: Anniversary Edition. Chris (my texture artist) is bringing his Surface to showcase our stuff. If you're gonna be attending the event, come find us! We've got a lot to show off and talk about. I'll most likely be posting on my twitter through out the event.

 

Unfortunately, the surface ran any Leadwerks project terribly, so we are only limited to our Source projects. :(

 

That's really it. I know I usually write an essay for blog posts, but I've been busy lately in preparation for Steam Dev Days. I'm really excited, as I never been on that side of the country before!

reepblue

Crawler's Den is a demo I made for the Summer Games Tournament this year. You can grab it here. This blog I'd like to share my reflections on developing the project on LEX2 and Leadwerks in general.

 

When I started the project, my template had no animation manger, and the puppeteer system was just coming online. The goal was to recreate the AI and Events map and write the entire thing in C++. Not only to test the puppeteer system and my ideas on how to link said puppeteers to the flowgraph, but I would have classes to derive from when I start working on Vectronic again. :)

 

Right now, LEX2 is a template that gets installed in the Templates folder of the Leadwerks App Directory. However, upon creating a template, I noticed that the project and sources didn't seem to copy over as they did in testing. I think it has to do with the project manager's date based system as I was on the beta branch when I started. So fixing my project was no biggie, but not something I'd like to ship out.

 

The player was the first thing to get coded as I wrote about here. I based my player code of the Source engine's player because I really like how that feels. It wasn't long until I had a player that can walk, jump, crouch, and use/pickup objects. Neat! I'm really happy how it turned out. There are some improvements I thought I can make, but it was drawing close to the deadline so it has to wait.

 

The animation system was next. Without it, no gun and no crawlers. I started transferring code line by line but I didn't understand how to convert for inpairs loops to C++. This is when CrazyCarpet got involved as he was very willing to help as he needed an animation system for his stuff too. It took a few days to iron out, and minus slight problems I'm having, it works pretty much the same as it's lua variant. You can read the topic here about it which includes a link to the final code on Aggror's Wiki.

 

Now having the animation system in place, the weapon was next. I first translated the FPSGun script from 3.2 as it was a lot simpler and it was something to get started. I later added bullets, and allowance of different weapon types although the project would just need a pistol.

 

The crawler was something I put on the backburner as I never did AI in Leadwerks before. I was aware of the functions, but never needed to use them. This was my first project where I needed to use the navmesh system too. I did level design next because I really wanted to start mapping.

 

I needed to start from scratch with the map. The AI and Events map used meters instead of centimeters so nothing lined up with the grid anymore. there was once an option to switch between the two measurements, but I guess Josh took it out, or it's under legacy features. Ether way, I wanted to use centimeters. I shelled the map out by eye and feel, I hardly went back to the source material as that would require switching the project and such. I had the map mostly shelled out before I started to work on textures.

 

I usually use Paint.Net for raster artwork, but I decided for this project to use an older version of Photoshop. Not only because it's "what the pros use" but I want to use a file format that could be readable in other software. PSDs can be read by gimp so if there comes a day in which I'm making games on a non-windows machine, I can still open psds. I should learn how to use gimp and ditch Paint.net as PDN is Windows only. But I wanted to make a game, not learn new software.

 

Now that I know how to properly port in models from blender, I had a lot of fun modeling for my scene. Making support beams, trims vents, and such was really fun, and everything got imported correctly. I had the best luck using FBX ASCII 6.2 versus the Binary 7.4 option, and Applying scale made sure that everything was sized correctly with a default scale setting as 1,1,1 like it should be. I couldn't remodel everything, I just remodeled things that wouldn't connect together right due to the measurement change. There was some old models I just used the model editors scale tool.

 

While building my level was really fun, optimizing was the exact opposite. I limited my shadows, optimized my prop settings, made lights smaller, and collapsed a lot of modular pieces together and with my 750Ti, I get 90fps in the first room and 70ish in the showdown room. One thing I always thought was a good idea was to develop on medium range hardware. If you were to develop on lets say a 980Ti, you could get away with a few more expenses, but throw it on an older card, and it might chug, Develop on a mid-range card, and it'll play fine on that, better on newer and powerful hardware. I was cutting batches and polys like crazy but I couldn't get to a point where the entire scene was 100fps. I've added a wireframe view mode to my console options to see what was being drawn that shouldn't in which made me develop a portal volume that could hide, or show all the objects in it's volume while ignoring collapsed brushes.

 

wireframe.jpg

 

I eventually ditched the portal volumes because of a bug that I didn't feel like fixing, and I only saw 5 more frames in the end which wasn't worth the flowgraph mess I had to do. If I could get it to be automatic and fix that bug, I might re-add it.

 

There was a time when I sent the project to CrazyCarpet to debug something and this is when I learned that my theory about developing on mid-range hardware was correct. He reported 100-120+ frames on his 980, and for some reason was getting better results on his 750. My PC is no spring chicken, but he was getting 100 frames all round on a 750, meanwhile I drop to 70 on my 750Ti? blink.png

 

While I'm really happy that my pain and suffering resulted in better performance on newer hardware, it'd be great if I could have those results on my end. dry.png

 

The deadline was drawing near, and it was time to do the crawler, and a few other classes. By this time, I've developed and successfully created a way for my puppeteer class to communicate with the flowgraph. In short, each puppeteer has it's own lua script in which you can set the values and write the inputs and outputs to the class. Inputs are handled through a message system while outputs are fired by the entitles component class. I'd have to write another blog on how it works but I'm sure weeks after I do, there might be an official way to link C++ classes to your game and the flowgraph. So I played with that converting more scripts to C++. Then it came time for the crawler.

 

The crawler was a bit more difficult, and this is when I noticed an issue with the animation manager. It wasn't playing looping animations correctly. A quick line comment of --n fixed this, but to this day there is a problem in which it has a hard time going from attacking to running. It defaults back to it's idle animation and then glides around. Might be my monster code, but I was going on the last few days and the map wasn't done yet.

 

I was using the beta branch for a while, then Josh pushed a broken build which put me back on 4.1. I noticed the editor runs more smoothly on the default branch than the beta branch. I would think that this has to do with a debug settings or garbage collection that's enabled when Josh does development and only turns it off during prime time. But then, the beta branch was "fixed" so I jumped to that while keeping my game on 4.1 (I archive releases). I noticed a bug with the probes, and my map got corrupted on it. Thankfully I made a backup, so I didn't lose everything. I went back to the speedy stable release, finished my map and went to upload it.

 

Uploading is always a chore on my connection. I really hate when I spend hours uploading something and then after all that it fails to upload due to some error. This is why the Vectronic Demo is out of date on the game launcher, and why Crawler's Den is only on my dropbox right now. I should have used my mobile data, but I didn't for some reason.

 

Ether way, besides a few small bugs, the project is out and playable using LEX2. Here is a summary of working with it.

 

Good:

  • No worry about back end stuff, besides somethings I needed to improve thanks to this project, I didn't have to spend a week writing window, context or world code.
  • Console was a god send allowing me to easily debug my map in-game. Loading whatever map I want without the editor or hard coding was pretty dope.
  • Once they were done, the puppeteers are really neat to work with. They are set up like lua scripts, and all the hooking is done in the base class.
  • The precaching and Asset Manager worked amazingly well. No more slowdowns on loading models in real time, and no crashes because you mistyped the path. Really handy!
  • I made a volume class for triggers and such. Works way better than collision based ones.

 

Bad:

  • Project's don't copy right with the project manager. Again, might be the date based system.
  • The input system isn't done. It uses SDL for it's input handling and there is a bug in which all inputs must be done in UpdateWorld. CrazyCarpet said he'll look at this so we can correctly place movement inputs in UpdatePhysics.
  • I feel as though Puppeteers should be called actors. They are called puppeteers because there was a class called Actor which was the actual entity doing the actions instead of a separate class controlling the entity.
  • A lot of commented out code. I need to delete some things I've commented out months ago.
  • It was kind of a pain to make sure the core code was synced up with the base project, the game project and the git repo. I want it so that all games off of LEX2 use the same Core files.
  • Some reason I couldn't derive from my volume triggers....

 

I have an idea for this going forward but I don't want to express it just yet. No matter how I go forward, the foundation is here to stay. It might get cleaned up, maybe edited a lot, but I don't see a need for a rewrite, it's all solid.

 

Thank you for reading this, I hope you have fun with Crawler's Den!

reepblue

I've started on my quest to make a full C++ has started today. I've noticed that LEX2 via the project manager didn't copy over as clean as it should, so I had to make the project from scratch which wasn't a big deal (for me). I should look into a way of getting that fixed.

 

After setting the project up, I noticed a few errors I was getting after I commented out the LUA_GAME preprocessor. It was a quick fix, and development went under way after that.

 

For this project, I'll need things that's already available in Lua as part of the SDK. The high priorities are the first person player, animation manager, first person weapon (the pistol) and the Crawler's AI. As I said before, I don't want to convert SDK scripts to C++, but instead write the code myself. I'll look at the Lua stuff only if I get stuck.

 

Today I found out that not everything will work when you convert Lua code to C++. I decided on the player as I've written it for C++ with my actor class, then converted it to Lua because of problems. Now I want to but it back to C++ as a puppeteer. It took a few hours line by line converted the code. When it was all done, I ran into a few issues.

 

First off was HOW to spawn it? I could use a puppeteer script like I mentioned in my last blog, but the player should be spawned dead last. So the best method was to create the player in LEX2's OnPostMapLoad function.

 


// This function is called when the program finished loading a map.

void OnPostMapLoad()

{

Entity* puppet = WORLD->FindEntity("Player");

FPSPlayer* player = new FPSPlayer(puppet);

}

 

This function is called at the every end of the level loading process. This is mostly so we don't hear the weapon being picked up while the map is loading, or a spawn sound like the Vectronic Demo.

 

I was then running into null values that were driving me crazy. I went back and predefined all empty values as NULL and I was still getting a crash. It turns out, I didn't have the bool function returning the right value. dry.png

 

Next was the footstep sounds. As I said before, I copied my fully working Lua player script and I noticed that the footstep sounds were playing too fast. I defined the value lastfootsteptime as an int in the header as 0, but when I did a system print of that value, it'd always return as 1. the fix was to define the variable before the footstep function instead of in the header as so:

 


int lastfootsteptime = 0;

void FPSPlayer::UpdateFootsteps()

{

if (lastfootsteptime == NULL) { lastfootsteptime = 0; }

 

// If we're moving and not in the air, play a step sound.

if (input[0] != 0 || input[1] != 0)

{

float speed = entity->GetVelocity().xz().Length();

if (entity->GetAirborne() == false)

{

if (speed > MoveSpeed*0.5)

{

long t = Time::GetCurrent();

long repeatdelay = 500;

if (t - lastfootsteptime > repeatdelay)

{

lastfootsteptime = t;

PlayFootstepsSound();

}

}

}

}

}

 

Last, I had to fix a Gimbal lock with picked up objects. This was because all variables in Lua and C++ work differently. So when going the lines one by one, I stored rotation values in a Vec3, and not a Quat.

 

After the first day of my summer game, I got a player that walks around, jumps, can crouch under tight spaces with working sounds! I just got a few things to tweak before going to the next thing which will probably be the animation manager.

reepblue

Status Report

I wanted to give you an update since this blog post and let you know how well (or not) I'm following those plans.

 

Blue Portals: Anniversary Edition (Skip this if you don't care..)

 

Sunday I pushed a long over due push to Steam for beta testers to play and give feedback. I don't like to push to Steam often as my connection isn't that strong so any uploads bigger then a few megabytes causes an upload failure, I usually split updates into multiple pushes to prevent such problems but sometimes you have to push one large file that'll cause a error. This time I instead used my unlimited 4G mobile data and I had way better luck, and will be using this method from now on.

 

We right now only have a small handful of testers and I wish to keep it that way for a little while longer. It's interesting to see the same play-tester play the same map in different updates regardless if anything changed. There was one map where no reports or issues where given from this tester last update. I barely changed the room, and this time they informed me that something felt impossible to achieve.

 

I also keep play-testers out of developer news. This way I can introduce something brand new to them and they can report back if they understood it and/or liked the idea. I really wish I was in a position to watch people using Steam's broadcasting service, but I think even with my mobile data, it'd be unwatchable due to the high ping that wireless services have.

 

Although I wished the teaser trailer was done last month, I'm happy to report that it's being worked on now. I've got a message this morning that the recording is done. It just needs to be edited and such. Really cool as the mod has a look and feel that we're happy with. I guess it's better that the stuff got recorded today than a month ago as a month ago some models still had their ambient occlusion maps for skins!

 

Overall, the mod is coming together very nicely. There are a few things I'm worried about but I'm sure time will allow me to answer more questions I have. I'll keep you posted on this as I see it as a major stepping stone.

 

LEX2

 

A few hours ago, I pushed a near final build of it. In-short, I've cleaned up the code, deleted useless classes and changed how somethings operate.

 

For example, LEX2 has this function called AssetManager:PrecacheGlobal(path) which you call when you want something to be pre-loaded in memory so your game can load it later without a hitch. This was done by calling AssetManager:PrecacheGlobal(path) in App:Start() and what it did was load those paths into a list. Then when ever the world loaded a new map, PrecacheList was called which loaded every asset in that list. Although you only needed to define the asset once, it still needed to be loaded multiple times!

 

In this blog, Josh mentioned that it's possible to load assets into one world and have it just sit in memory while your game world is active. I decided to try this, but I was careful to prevent two worlds from being current at the same time.

 

First, I retired the old PrecacheList and made a new function.

 


void AssetManager::PrecacheJunkyard()

{

DevMsg("AssetManager: Creating Junkyard.");

 

// Save the current world if we have one.

World* oldworld = WORLD;

junkyard = World::Create();

World::SetCurrent(junkyard);

 

// Precache global objects.

std::list<std::string>::iterator it;

for (it = precache_list.begin(); it != precache_list.end(); ++it)

{

if (it->c_str() != S_NULL)

{

AssetManager::Precache(it->c_str());

}

}

 

// Go back to the 'real' world if there was one.

if (oldworld != NULL)

{

World::SetCurrent(oldworld);

}

else

{

World::SetCurrent(NULL);

}

 

}

 

This will load all the assets in the list that PreacheList used into a different world than the game. Then if there is ever the chance that a world exists when the junkyard world is created, it'll go back to it. To prevent that ever happening though, I made this function not exposed to Lua and have it called at the very end of App::Start() in C++.

 

bool App::Start()

 

{

//Create a window

windowmanager.CreateWindow(System::AppName);

 

// Create a context

contextmanager.CreateContext();

 

...

 

 

#ifdef LUA_GAME

// Finally, test the app script

if (ScriptApp::Start() == false)

{

#ifdef WIN32

MessageBox(NULL, "Error: Failed to execute App script!", "Critical Error!", MB_OK | MB_IConstop); //MB_ICONWARNING

#endif

return false;

}

#else

if (GAME::Start() == false)

{

return false;

}

#endif

 

...

 

// If the user preached anything in App:Start() or GAME::Start(), load them in another world.

// The Junkyard world will keep those entities in memory.

AssetManager::PrecacheJunkyard();

 

...

 

return true;

}

 

So then your Lua script will look like this

 

function App:Start()

AssetManager:PrecacheGlobal("Models/Characters/hitbox.mdl")
AssetManager:PrecacheGlobal("Models/Junk/cinderblock.mdl")

return true
end

 

But wait! What if you want the game to automatically launch a map? I didn't want a conflict where a world would exist, and then another world gets created to spawn assets. For safety measures, I just made a PostStart() function for Lua, and have it called after AssetManager::PrecacheJunkyard().

 


{

.....

 

// If the user preached anything in App:Start() or GAME::Start(), load them in another world.

// The Junkyard world will keep those entities in memory.

AssetManager::PrecacheJunkyard();

 

#ifdef LUA_GAME

ScriptApp::PostStart();

#else

GAME::PostStart();

#endif

 

return true;

}

 

-- This function will be called right after when the program starts.
function App:PostStart()
end

 

I really didn't test what would happen if I did load a map before AssetManager::PrecacheJunkyard(). I assume there would be a pause, as the worlds get swapped around, but I'm a bit too scared to try.. but also kind of curious...

 

I've also sorted the filesytem. Everything LEX2 is within Source/Core with one cpp file looking like this.

 


// $PROJECT_NAME_main.cpp.

#include "Core/base.h"

 

#ifndef LUA_GAME

namespace GAME

{

// This function will be called once when the program starts.

bool Start()

{

return true;

}

 

// This function will be called right after when the program starts.

void PostStart()

{

}

 

// This is our main program loop and will be called continuously until the program ends.

bool Loop()

{

return true;

}

 

// This function is called when the program is loading a map. (This is where you draw your loading screen!)

void OnMapLoad()

{

}

 

// This function is called when the program is called to pause.

void onpause()

{

}

 

// This function is called when the program is called to resume.

void onresume()

{

}

 

// This function is called when the program finished loading a map.

void OnPostMapLoad()

{

}

 

// This function is called when the program disconnected from a map.

void OnDisconnect()

{

}

 

// This function is called when the program closes.

void OnShutdown()

{

}

 

// C++ function only. This is how you link editor entities to your C++ classes

void LoadEntity(Entity* entity)

{

/*

// Attach loaded entites to puppeteers.

// This can get long and messy, there is some talk about this getting auto-generated with an offical actor class.

// Cross your figners for that day....

Puppeteer* puppeteer = NULL;

if (entity->GetKeyValue("puppeteer") == "Rocket")

{

puppeteer = new Rocket(entity);

}

else if (entity->GetKeyValue("puppeteer") =="Demon")

{

puppeteer = new Demon(entity);

}

else if (entity->GetKeyValue("puppeteer") =="Portal")

{

puppeteer = new Portal(entity);

}

*/

}

}

#endif // !LUA_GAME

 

As you can see, it's pretty much exactly like App.lua. If LUA_GAME isn't defined, it calls this code instead of the App.lua file. I did this to make making a game for C++ and Lua very similar. There is a function that gets called within the MapHook to link entities to the Puppeteer class which can be linked with one script.

 

Script.puppeteername="" --choiceedit "Puppeteer" "foo,boo"

function Script:Start()
-- Attach us to a C++ class like this!
self.entity:SetKeyValue("puppeteer",puppeteername)
end

-- There needs to be a better way of flowgraphing with C++ classes!!
function Script:User1()--in
self.component:CallOutputs("User1")
end

function Script:User2()--in
self.component:CallOutputs("User2")
end

function Script:User3()--in
self.component:CallOutputs("User3")
end

function Script:User4()--in
self.component:CallOutputs("User4")
end

 

 

Summer Games Tournament

 

As I stated, I much want to participate in this one. I don't really have much time to make a unique piece, but I want something to stress test LEX2 and see if it can be used easily and effectively. I'm thinking about my take on the AI and Events map from the Advanced First-Person Shooter Template. That map kind of bothers me as the scaling is all wacky (It was made when the editor used Meters) and I feel that it's in the one person team field of difficulty.

 

Seems easy, where's the challenge? Well, While the end result will be a revision, I want to remodel most assets and code the entire game in C++ using LEX2's puppeteer system! I also will be coding things to my preferences so it's not like I'm just gonna convert existing Lua code to C++.

 

I had other ideas but this seems like the best one currently. It should be an interesting project, and I'll open-source it when I'm done. Anything I make will be available for others to use in the future. I wish to start tomorrow; or when I wake up as it's past midnight.

 

 

Steam Dev Days

 

I'm making arrangements to go to Steam Dev Days this year. I've bought my ticket and I just got a few things to iron out with traveling, hotel, and some company naming conflict. My overall goal is to talk to network with other people, talk about developing games, and learn new things. I'm really stoked about the entire thing.

 

 

That's all for now, wish me luck!

reepblue

Lua or C++?

Through out the Leadwerks community you'll find two types of users. You'll find a large portion of the community using lua, and a small dosage of them using C++. This makes sense as people are more often going to purchase Leadwerks without any DLCs (including the Professional Edition), and get into developing. From experience, Leadwerks at the moment puts it's primary focus on Lua scripts with it's script editor and debugger, flowgraph editor, and the script property system. Everything is pretty straight forward and it's quick and easy to prototype and develop your games. Throw in an entity in the editor, attach a script to it, adjust some values, set up connections and you're done!

 

You'll also find a smaller chunk of the user base talking about C++. Unfortunately.as of writing this blog post, a life of a C++ user is more difficult. For one thing, we don't have any connection with the editor so any entitys we want to put in our game need to be done during run time. If you made this cool monster in C++, you'd also need to make a system so your level designers (or you) can place them in the levels. Some examples of this is people using editor placed pivot's names as spawn markers. And even if then, you'd have to make a Lua script for that pivot to send any custom/modifiable values or special events to the C++ class. Not to mention, you'll need to search around how to communicate both languages together. And if people are suborn about learning Lua, they'll end up making systems that conflict with existing features/editor Things get messy fast when making gameplay with C++.

 

Ok, so why do we bother then? While Lua is an ideal choice for gameplay, but what about the rest of your game? You still need to control how your window, context and world handles, how user settings get applied, and a lot other gross stuff that goes into a game. You can use Lua for that, but you'll run into two issues. For one, if you're working with a team, you'll have to trust them not to touch anything relating to the under the hood stuff unless they know what they are doing. You'll also have that paranoia of slow down due to using Interpreter for everything. You'll need a lot of script logic to cause any slow down, but who knows what you're doing when it comes to the background stuff.

 

My solution is easy, use both together!

 

My application Leadwerks Extended Executable is designed to handle all the yucky bits in the application side of things while you can use the engine as intended. All it does is instead of launching main.lua, it calls a App class which handles the window, context, and world along with reading user settings. As of version 2, you can communicate to the C++ classes in Lua with the AppManager Class

 

-- This line will spam We're Connected" if we're in a map.
if AppManager:IsConnected() then System:Print("We're Connected") end

 

All the guts are "locked out" for the rest of the team so you don't need to worry about Mike from the art department accidentally touching the window handling system, and setting the project back a few weeks.

 

LEX2 also has 2 classes to accommodate for C++ gameplay classes, Actors, and Puppeteers. Puppeteers act like a Lua script. You attach an entity to the class and write the code like if you were writting a Lua Script. We're still lacking an efficient way to connect an editor entity to a class. I tried to use a Lua script, but due to the fact you'd need a script per puppeteer for it's custom values and flowgraph support, you might as well just write the damn code in Lua and be done!

 


#if !defined( PUPPETEER_H )

#define PUPPETEER_H

#pragma once

 

#include "base.h"

 

namespace Leadwerks

{

// Puppeteer's are pretty much the C++ version of lua scripts.

// While using this class, keep note that this class doesn't exist in the game world.

class Puppeteer : public Object

{

public:

Puppeteer(Entity* pEntity);

virtual ~Puppeteer() {};

 

virtual void Start() {};

virtual void PostStart() {};

 

virtual void Collision(Entity* pEntity, float* position, float* normal, float speed) {};

virtual void Draw(Camera* camera) {};

virtual void DrawEach() {};

virtual void PostRender(Context* context) {};

virtual void UpdateMatrix() {};

virtual void UpdatePhysics() {};

virtual void UpdateWorld() {};

 

void Detach();

void RemoveAll();

 

Entity* GetPuppet()

{

return entity;

}

 

Entity* entity; // The entity we'll be controlling. Was gonna rename this to 'puppet', but I want programing Puppeteer classes to be the same as scripting in lua.

 

// We can get script values like this.

bool GetBoolValue(std::string pValve)

{

return entity->GetBool(pValve);

}

 

float GetFloatValue(std::string pValve)

{

return entity->GetFloat(pValve);

}

 

int GetIntValue(std::string pValve)

{

return static_cast<int>(entity->GetFloat(pValve));

}

 

std::string GetStringValue(std::string pValve)

{

return entity->GetString(pValve);

}

 

protected:

static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed);

static void DrawHook(Entity* entity);

static void DrawEachHook(Entity* entity);

static void PostRenderHook(Entity* entity);

static void UpdateMatrixHook(Entity* entity);

static void UpdatePhysicsHook(Entity* entity);

static void UpdateWorldHook(Entity* entity);

};

}

 

#endif //PUPPETEER_H

 

 

There are also Actors. Unlike how Puppeteers work in which you assign an entity to it, this time you're building on top of the object. and it exists in the world. It's only really good for players, but I ran into a pickle recently where the player would not spawn in the position I tell it to. I ended up translating the entire code to Lua and it works as intended. with the bonus of the flowgraph mind you.

 


 

#if !defined( ACTORS_H )

#define ACTORS_H

#pragma once

 

#include "base.h"

 

namespace Leadwerks

{

// Actors are the entites, but behaving like it's under a lua script or Puppeteer.

// Unlike scripts or Puppeteers, this class was ment to be the base of controlling the ACTUAL entity, without a middle class.

class PivotActor : public Pivot

{

public:

PivotActor(Entity* parent = NULL);

virtual ~PivotActor();

 

virtual void Collision(Entity* entity, float* position, float* normal, float speed) {};

virtual void Draw(Camera* camera) {};

virtual void DrawEach() {};

virtual void PostRender(Context* context) {};

virtual void UpdateMatrix() {};

virtual void UpdatePhysics() {};

virtual void UpdateWorld() {};

 

protected:

static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed);

static void DrawHook(Entity* entity);

static void DrawEachHook(Entity* entity);

static void PostRenderHook(Entity* entity);

static void UpdateMatrixHook(Entity* entity);

static void UpdatePhysicsHook(Entity* entity);

static void UpdateWorldHook(Entity* entity);

};

 

class ModelActor : public Model

{

public:

ModelActor(std::string pPath, Entity* parent = NULL);

virtual ~ModelActor();

 

virtual void Collision(Entity* entity, float* position, float* normal, float speed) {};

virtual void Draw(Camera* camera) {};

virtual void DrawEach() {};

virtual void PostRender(Context* context) {};

virtual void UpdateMatrix() {};

virtual void UpdatePhysics() {};

virtual void UpdateWorld() {};

 

protected:

static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed);

static void DrawHook(Entity* entity);

static void DrawEachHook(Entity* entity);

static void PostRenderHook(Entity* entity);

static void UpdateMatrixHook(Entity* entity);

static void UpdatePhysicsHook(Entity* entity);

static void UpdateWorldHook(Entity* entity);

};

 

class CameraActor : public Camera

{

public:

CameraActor(Entity* parent = NULL);

virtual ~CameraActor();

 

virtual void Collision(Entity* entity, float* position, float* normal, float speed) {};

virtual void Draw(Camera* camera) {};

virtual void DrawEach() {};

virtual void PostRender(Context* context) {};

virtual void UpdateMatrix() {};

virtual void UpdatePhysics() {};

virtual void UpdateWorld() {};

 

protected:

static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed);

static void DrawHook(Entity* entity);

static void DrawEachHook(Entity* entity);

static void PostRenderHook(Entity* entity);

static void UpdateMatrixHook(Entity* entity);

static void UpdatePhysicsHook(Entity* entity);

static void UpdateWorldHook(Entity* entity);

};

 

// TODO: Maybe make a SpriteActor?

}

#endif //ACTORS_H

 

 

It was kind of hard writing this entry as I work with both languages. I guess the overall message is to chose you're battles and do what's in your skill set and preferences. I'd still love there to be an easy way to code gameplay elements in C++ like I do with Source. The class hierarchy system really comes in handy as you can just make a bunch of base classes and build off of them as needed. Hopefully, this will get addressed soon. In-fact, I actually made this blog post in reflection of this forum post. Maybe someday we can make our games fully in C++ and have access to the flowgraph editor and to be able to set custom properties!

reepblue

It's been over a year ago since I've released the Vectronic Demo using Leadwerks. The demo was composed of assets I've made ported from the Source Engine and my lack of understanding of the API and lua scripting at the time. (I'm used to coding everything in C++) As of writing, it has 1,221 subscribers on the Steam Workshop, 25 out of 26 positive ratings, and is the second most subscribed item! So there is sigh that this as a MVP (Minimum Viable Product) was a success. And again, the Game Launcher is in Beta..

 

Since the demo, the engine got a lot of improvements and features, and I've learned a lot more about game development in general. (Models, Texture making, etc.) Last summer, I sat down to develop a base application for my projects. I wanted the world, context, and window management to be out of the way while making the full game, and I was concerned about a UI as it was a sticking point when I did a Source branch change from the 2013 SDK to the Alien Swarm Branch in favor of better development tools. (That engine is really fragmented when it comes to things like that....)

 

Once I finished that application; LEX, I then started over developing the game using that template. Two months went by, I've done some interesting puzzles in dev textures.but I felt that one element was taking over the vecball power elements. It was more fun to use that than fire balls at boxes. (And it was more work than the Vecballs) So, I paused development on that project to research if that 'thing I added' would be a better focusing point.

 

I only spent a week on it. I didn't want to work on it too much, just enough to see if it'll work. It turned out, that minus some placement calculation, it was really fun. As you can see, I don't want to talk about it in-case I decide to go with it.

 

November was approaching again, and it's a special time for me. In 2010, I released my Portal mod Blue Portals with mostly positive reviews. Every November, I like to do something to give a reason for people to revisit it. Last year (2014) I fixed the mod so it'd work with the steampipe update, and last November, I decided to put the mod on Steam as an "Anniversary Edition"

 

Although we had massive support about Blue Portals on Steam, there was things I wasn't happy about, and prevented me from putting it on Steam earlier. Some things didn't age well and I've made some poor design choices. There was also some criticism over the difficulty curve (which is kind of common with Portal mods), and somethings just broke. I can spend a few months patching it up, or I can take the extra time and reevaluate the entire project, and have it be a quality mod on Steam. Plus, if the difficulty curve was adjusted, more people can actually play it!

 

This first started as a revamp project, but slowly became it's separate entity with it's own needs. I'm learning a few new things I've haven't known before, and it's interesting how some concepts/techniques I've learned using Leadwerks came into play here. I was first very worried about Vectronic being on the back burner, but then I realized that it's actually a good thing I take a break from Vectronic for the following reasons:

 

  • I can experiment with marketing, community management, updates with little to no risk. I can try something and see how it goes and decide what I did right and/or wrong with that decision and use it in the future.
  • I can get used to Steamworks, and have an idea going into Steam Greenlight how it's gonna be, which is a plus over most indie devs who need to take time to learn that stuff.
  • Blue Portals: Anniversary Edition can be/will be used as an advertising piece for future projects, I can comfort future consumers with an example of our work before they vote on Greenlight or purchase it on Steam.
  • I was really unsure where to take the project, so coming back with a clear head would help. I have a bunch of ideas now, but not gonna jump into anything now.

 

 

I see the Blue Portals: Anniversary Edition project (BPAE) as a stepping stone for marketing and consumer confidence. Since the mod can be downloaded with zero risk to a consumer, I feel better taking chances with it then I would a product I'd wish to sell. So what's the battle plan?

 

  1. Continue to develop BPAE. I'm aiming for a December release. Since most research and development have been conducted five years ago, I think if my team and I keep working at it, we can have a polished product on Steam which in return can help sales with Vectronic. I plan on starting to experiment with Marketing next month. I really want to find that "How Early is the right time to show?" mark. My first guess is "When the project has an established direction, but nothing is 100% final just yet.". Which for this project is short of 6 months of development.
     
  2. Continue to chip away at LEX2 as it's going be the new foundation. Unlike it's predecessor, the solution is very minimal and allows for easy C++ entity implementations. I want to participate in the next Tournament using it to make sure it's all solid and good.
     
  3. When BPAE is wrapping up, start programming the yucky gross parts like the player and some custom collision rules. Start thinking how everything will tie together and use the new things I learned with BPAE while making design and development choices. I think doing this while BPAE becomes a touch up project will allow me to not feel like I'm doing the same things on two projects.
     
  4. Start the true cycle of development for Vectronic once BPAE is submitted to be released on Steam.

 

 

So that's the plan. Taking this one at a time. I'll keep you posted on what I'm doing like always. Although Blue Portals: Anniversary Edition isn't a Leadwerks project, I still think me writing my findings with it can benefit others while making their games. We're all learning here!

reepblue

For the past few months, (on top of working on my greenlit mod) I've been developing a new foundation for Vectronic that will take care of all the 'internal yucky bits' such as window/context/world management, and other features and functions. I really wasn't happy how the first implementation came out as I felt like I was taking too much from the developer, and it was messy and confusing to do something simple like adding a loading screen.

 

LEX2 is more lua friendly, not bloated with scripts that you may or may not use, and has more comments than my Blue Portals 2 video in the code! You just need the executables, App.lua, and engine.pak which contains standard assets that the application will call if something is missing.

 

You can play with it here. I've used the latest beta with probes so if you don't have the probe beta, don't load map 07 I guess. Here are somethings you might notice looking at scripts or general usage.

 

 

Developer Console:

 

lex2eval1.jpg

 

LEX2 comes with a developer console for visually debugging your game while you play. Draw stats, show physics, show navigation, or change settings on the fly. All commands use the standard system properties.

 

lex2eval2.jpg

 

To access the console, the game must be started with -dev or launched from the editor. When the game is paused, it the tilde key (`) and start typing. Hit Enter to submit your command. You can use PageUp and PageDn to scroll through pass commands.

 

You can type 'help' to report a list of current commands. There is no display box, so it's best used when the game is windowed with the log from the script editor visible.

 

 

Asset Manager:

 

self.sound = Sound:Load(AssetManager:Check("Sound/MySound.wav))

 

Never crash again because you moved something or mistyped an asset. AssetManager:Check() returns a error asset from engine.pak if what you've sent is not found. The game will not start at all unless the error assets are found at startup.

 

You can also easily preload models for later use with AssetManager:Precache(string). You can also make a Precache list with AssetManager:PrecacheGlobal(string). This is great if you have a model or prefab that might spawn at anytime in any map.

 

 

PostStart():

 

PostStart is a command fired after the level loads instead of during it like Start does.

 

function Script:Start()
self.source = Source:Create()
self.source:SetVolume(self.volume/100)
self.source:SetPitch(self.pitch)
self.source:SetLoopMode(self.loop)
self.source:SetRange(self.range)
self.source:SetPosition(self.entity:GetPosition(true))
end

function Script:PostStart()
local sound = Sound:Load(AssetManager:Check(self.soundfile))
if sound~=nil then
self.source:SetSound(sound)
if self.playing==true and self.enabled==true then
self.source:Play()
end
sound:Release()
sound=nil
end
end

 

 

Input System:

 

if Input:Forward(true) then self.input[1]=self.input[1]+1 end
if Input:Backward(true) then self.input[1]=self.input[1]-1 end
if Input:Right(true) then self.input[0]=self.input[0]+1 end
if Input:Left(true) then self.input[0]=self.input[0]-1 end

 

You can now allow your player to change their controls. by calling a general function. Controls can be controlled with System:SetProperty or by editing settings.config. The control commands are based off of the default steam controller layout. I just need too add previous/next weapon, but wasn't 100% sure how I was gonna do that since it may be a scroll wheel.

 

 

Basic UI System:

 

Use Lua to create your own UI with LEX2's exposed UI classes. If you replace the app start and loop functions with this code, it'll make a square in the corner with a text button that says "Leadwerks".

 

--This function will be called once when the program starts
function App:Start()
Rect = UIRectangle:Create(4,4,200,200)
Rect:SetColor(40, 40, 40)
Rect:SetBorderLineWidth(4)
Rect:SetBorderColor(92, 92, 92)
Rect:EnableBorder(true)
Rect:Hide()
local testfont = Font:Load(AssetManager:Check("Fonts/consola.ttf"), 20)
Rect3 = UIText:Create(Rect:GetCenter().x, Rect:GetCenter().y, "Leadwerks", testfont, "Test");
Rect3:Center();
Rect3:SetShadowMode(false)
Rect3:SetAsInteractive(true)
Rect:AddChild(Rect3);
return true
end
--This is our main program loop and will be called continuously until the program ends
function App:Loop()
context:SetBlendMode(Blend.Alpha)
-- Here is code to darken the scene when the game is paused.
if self:IsPaused() and self:IsConnected() then
context:SetColor(0,0,0,0.5)
context:DrawRect(0,0,context:GetWidth(),context:GetHeight())
end

Rect:Update()
if (Rect3:GetMouseEvent() == Rect3.MouseLeftUp) then
System:Print("Pressed!")
elseif(Rect3:GetMouseEvent() == Rect3.MouseOver) then
Rect3:SetColor(100, 100, 100)
elseif (Rect3:GetMouseEvent() == Rect3.MouseLeftDown) then
Rect3:SetColor(80, 80, 80)
else
Rect3:SetColor(255, 255, 255)
end

if window:KeyHit(Key.F11) then
if (Rect:IsVisible()) then
Rect:FadeOut()
else
Rect:FadeIn()
end
end

context:SetBlendMode(Blend.Solid)

return true
end

 

I haven't really did much with the UI as it's a future feature of the engine, plus I've been playing with other stuff. But with UIRectangle and UIText is pretty much the foundation of buttons, sliders and other stuff anyway. Or you can use another UI library if you want.

 

Again, you can play with it by downloading the project here:

https://dl.dropboxusercontent.com/u/16218991/Requests/LEX2Test.7z

 

I'm really stress testing it now making sure I don't have to touch anything when I'm ready to revist Vectronic. Speaking of Vectronic, it's almost been a year since I've released the demo. I might later this week write a blog about it and my battle plan for it.

reepblue
blog-0897650001463479620.png

If you join the beta branch and updated your projects, you'd probably noticed that the low res Leadwerks 2 icons have now been replaced with high resolution ones that match the rest of the user interface. Decals, Particles Emitters, Cameras, and Probes now have their own icon, and you can tell all entities apart just by looking at them.

 

I've originally made these a while ago when I noticed that each entity had it's own material and texture, but most of them just recycled the pivot icon. I've released a version on the workshop, and an updated version as part of the LEX template. Yesterday, Josh contacted me about using them in the official build, and I was more than happy to say yes, and make any wanted changes. He mostly wanted the lights to be yellow, and I've changed the angle of the spotlight to be more downward.

 

Each icon texture is 512x512 uncompressed, and was made using a vector art program so the icons are sharp and clear as possible. These icons will be skipped during the packaging process, so they will not bloat your final game.

 

You can get these icons by joining the beta branch and updating your project. These icons will be released as part of Leadwerks 4.1. If you think anything needs to be changed, let ether Josh or I know.

 

I think the only thing left to do is update the light buttons on the side, really. Here's a mock up of what it can look like. To be honest, I think they kind of clash with the other icons as those where shipped with 3.0 which had some sort of a Windows 7 icon pack for everything else.

 

iconsmockup.png

reepblue
blog-0233614001460007417.jpg

With the recent popular substance shader by Shadmar, more talk and focus has been about cubemap reflections surfaced in the community. Reflections in Leadwerks were done in the past with the SSLR post process shader which made all surfaces reflect the world in real time.

 

 

 

 

However, it had the following problems:

  • It was applied to ALL materials in the scene. If you had a material that wouldn't normally reflect such as concrete or wood, the shader would still effect those materials. Basically, the texture artist had little control.
  • The post process shader needed to be first on the list, and some people didn't understand that.
  • You could adjust the reflections by the model's alpha color. But if you had any shader that relied on the alpha mask for map blending or something else, you're out of luck!
  • The reflections distorted based on camera angle, and not really great for in-game action.
  • Like everything OpenGL, there is/was a chance it wouldn't work well with AMD gpus.

 

This was all we had until in February, Mattline1 posted a blog on his PBR system, which included a block of code that built a world cubemap and swapped the cubemap texture with it. Thankfully, he uploaded is source code so anyone who has the professional edition could download his code and have a look.

 

While his implementation is very nice, it has the following design flaws for a typical Leadwerks user.

  • You needed to use only the PBR shader. Normal Leadwerks shaders didn't render well.
  • Needed a Post process effect to adjust the gamma of the scene.

 

Weeks later, Shadmar uploaded his version of a Substance/PBR shader which allowed users to still use their existing shaders, and gave artists more to work. Since it's a shader, and not a full implementation like Matt's, it didn't have the world reflection system. I've been busy with a lot of Source engine work, but seeing how much interest this is getting lately, I decided to take a few days off and see if I can make my own cubemap system.

 

 

The Implementation

 

A disclaimer, this is not a full "How-To" as you'll need to add it to how your application, and it'll most likely do things differently than how I have my application set up.

 

First, we need to figure out how we are gonna get a world cubemap to a texture. While it's not the most "next-gen" way of doing this, I decided to base my system off of the Source engine because, well I know how it works, and it's pretty simple. It goes like this:

  1. Mapper places a env_cubemap entity near a shinny surface. (Any material set to use cubemaps.)
     
  2. Mapper compiles and runs the engine.
     
  3. Mapper than types "buildcubemaps" into the console.
     
  4. For each env_cubemap entity, 6 "pictures" are taken (up, down, left, right, forward, and back). than those textures are saved within the bsp.
     
  5. The map restarts, and the surface will use the near by cubemap texture.

 

Great, that seems very straight forward, and we can remove steps 2 and 3 as there is no compling in Leadwerks, and everything should just work. The first thing we need is a 3D point in the world that'll act as our env_cubemap.

 


class Cubemap : public Pivot

{

public:

Cubemap(Vec3 pos = NULL); //lua

virtual ~Cubemap() {}

...

...

...

};

 

We build off of the pivot class because we want this to actually exist in our world, not be a "puppeteer" for a pivot entity. We also have the position being set in the constructor as the only way to get our custom entity into the world is by a lua script. Using ToLua++ we can make a script that we can attach to a pivot/sprite.

 

function Script:Start()
local n = Cubemap:new(self.entity:GetPosition(true))
self.entity:Hide()
end

 

This script will spawn our cubemap entity at our editor placed pivot, then hide the editor placed pivot. Basically, we swap the entities during level load.

 

This cubemap entity job is to search for near by entites, (Which I currently have set to it's aabb radius + a range float) then change it's surface material with a copy of what it had, only with a different cubemap texture. Early in development, I just have the entity fix the cubemap texture to the current world's skybox to make sure that this would work.

 


 

 

void Cubemap::SetReflectionTextureToSkybox(Leadwerks::Surface* surf)

{

if (WORLD == NULL) { return; }

if (WORLD->skyboxpath == "") { return; }

if (!surf) { return; }

 

Material* mat = surf->GetMaterial();

if (!mat) { return; }

 

// Make this faster, if there is any indication of a surface not using the substance shader, abort the cubemap application!

 

// If there is no cubemap assigned, then we can skip this object.

if (mat->GetTexture(6) == nullptr) return;

 

// if the metal value is 0, we can skip.

int matspecmetalness = mat->GetColor(COLOR_SPECULAR).w;

if (matspecmetalness == 0 ) return;

 

Material* copy = (Material*)mat->Copy();

 

if (copy != NULL)

{

Texture* cubeTexture = Texture::Load(WORLD->skyboxpath);

copy->SetTexture(cubeTexture, 6);

surf->SetMaterial(copy);

 

cubeTexture->Release();

copy->Release();

}

}

 

Before we go into building the world cubemaps, we need to add this to the entity's header. This will make it so we can pass a texture to the entity:

 


Texture* SavedMap;

Texture* GetCubemap()

{

return SavedMap;

}

 

Now to the cubemap factory, which on map load will find all of our cubemap entites, do the texture building or each entity, Set SavedMap to the new cubemap texture, then tell the cubemap entity to look for near by entities so it can do it's replacement job. Thankfully, all the yucky stuff has been done by Matt, so I just needed to cut the stuff I didn't need, and make it handle multiple level loads and disconnects to work with my worldmanager class.

 

Here's a few snip of this process.

 


 

bool CubemapFactory::initialize()

{

Release();

...

...

...

 

int i = 0;

do

{

if (WORLD->GetEntity(i)->GetKeyValue("cubemap", "0") == "1")

{

Cubemap* pCubemap = dynamic_cast<Cubemap*>(WORLD->GetEntity(i));

if (pCubemap != NULL)

{

// Build the cubemap

cubeTexture = Leadwerks::Texture::CubeMap(

reflectionResolution,

reflectionResolution,

Leadwerks::Texture::RGBA,

Leadwerks::Texture::Mipmaps

);

 

cubeTexture->BuildMipmaps();

Leadwerks::OpenGL2Texture* gl2cubeTexture = dynamic_cast<Leadwerks::OpenGL2Texture*>(cubeTexture);

glActiveTexture(gl2cubeTexture->GetGLTarget());

glBindTexture(GL_TEXTURE_CUBE_MAP, gl2cubeTexture->gltexturehandle);

glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

 

 

// Apply it!

GenerateReflection(pCubemap->GetPosition()); //<-- generate first reflection texture

GenerateReflection(pCubemap->GetPosition()); //<-- use initial texture to generate correct texture

if (cubeTexture != nullptr)

{

pCubemap->SavedMap = cubeTexture;

}

 

// Tell the cubemap to look for near by entities, and replace it's cubemap texture with cubeTexture

pCubemap->SearchForEntites();

cubeTexture->Release();

}

}

i++;

} while (i < WORLD->CountEntities());

...

...

...

CubemapFactory::init = true;

}

 

GenerateReflection() is pretty much the same as Matt's PBR project. That function actually does the "camera work", and saves the result in a Texture. This is done on the fly during level transition.

 

 

Skipping Dynamic Objects

 

There is just one problem however. Everything is being rendered when the cubemaps are being built. So any enemies, or move-able objects will be baked into a reflection. To fix this, we need to have all objects that can move (Mostly have mass) be hidden, and then re-shown after we've finished the building of cubemaps.

 

Pretty much.

 


#define S_NULL ""

#define ON "1"

 

void ShowMoveables(Entity* entity)

{

if (entity != NULL)

{

 

if (entity->Hidden() == true && entity->GetKeyValue("hide_for_cubemap", S_NULL) == ON)

{

entity->Show();

entity->AddForce(Vec3(0, 0, 0)); // <-Wake me!

entity->SetKeyValue("hide_for_cubemap", S_NULL);

}

}

}

 

void HideMoveables(Entity* entity)

{

if (entity != NULL)

{

// Things to look for ar entites with the mass > 0, or have their shadow mode non static!

if (entity->GetMass() == 0 || entity->GetShadowMode() == Light::Static)

return;

 

// Only hide the non-hidden!

if (entity->Hidden() == false)

{

entity->SetKeyValue("hide_for_cubemap", ON);

entity->Hide();

}

}

}

 

void MapHook(Entity* entity, Object* extra)

{

// For cubemap generation, we don't want anything that's set to move to be built in with our cubemaps.

HideMoveables(entity);

}

 

 

bool WorldManager::Connect(std::string pMapname)

{

...

 

if (Map::Load(pMapname, &MapHook) == false)

return false;

...

return true;

}

 

 

//--------------------------------------

// For cubemap building!

//--------------------------------------

void WorldManager::MakeMoveablesVisible()

{

vector<Entity*>::iterator iter = entities.begin();

for (iter; iter != entities.end(); iter++)

{

Entity* entity = *iter;

ShowMoveables(entity);

}

}

 

Then back in the initialize function of our cubemap factory before we return true.

 


 

// Lastly, redraw moveables!

worldmanager.MakeMoveablesVisible();

 

And now anything that has mass, or has it's ShadowMode set to Dynamic will not be baked into the reflection!

 

 

Cleaning up

 

To make it so that this can work with multiple level loads and when the game "disconnects" (Not in a map), we need to reset everything.

 

Cubemap factory:

 


 

void CubemapFactory::Render()

{

if (WORLD != NULL || worldmanager.IsConnected() == true)

{

if (!CubemapFactory::init) { CubemapFactory::initialize(); }

WORLD->Render();

}

}

 

void CubemapFactory::Release()

{

System::Print("Clearing Cubemaps!");

CubemapFactory::init = false;

if (cubeTexture != NULL)

{

cubeTexture->Release();

}

CubemapFactory::currentContext = nullptr;

CubemapFactory::reflectionCamera = nullptr;

CubemapFactory::cubeBuffer = nullptr;

CubemapFactory::cubeTexture = nullptr;

}

 

And instead of calling world->Clear in my world manager, I instead call this function:

 


 

void WorldManager::ClearWorld()

{

CubemapFactory::Release();

world->Clear();

}

 

Calling CubemapFactory::Release() may not be necessary as it's called everytime the factory is initialized, but it doesn't hurt to be safe!

 

 

Conclusion

 

It was a ride getting this to work correctly. I'm still not happy about how the cubemaps look for near by entities, but it's better than what we have now, which is nothing, Apperently, Josh is concidering this as a engine feature so all of this work might just be temp until he adds it in, which hopefully will be smoother and less error prone!

 

I may consider adding "environment probes" like Source has. They would basically work exactly the same way as what Scrotie did.

 

But what we have a system that works like this:

  1. Engine loads a map, world created, etc.
     
  2. A map hook hides any entities that has mass or a dynamic shadow mode.
     
  3. Cubemap Factory takes it's "pictures" much like Source does when buildcubemaps is executed.
     
  4. Each cubemap texture is given to the right Cubemap entity, then released.
     
  5. The cubemap looks for near by entites and swaps the model surface's default cubemap with the one it got from the factory.
     
  6. Cubemap factory tells the world manager to re-show the entities it hid.
  7. Things continue as normal.

 

 

 

So that's it! Thanks for reading!

reepblue

Vectronic: Week 7

Sorry for the whole week of silence, I ran into quite into a number of issues the previous weeks, but I'm ready to talk about them more, and how I it got resolved.

 

Newton Physics (Or how Leadwerks uses this physics engine) has a problem when a non-physics object collides with a physics object. You expect that if a entity using the Move() function would use it's own shape to push anything out of the way. What actually happens is that since the entity has no mass, the entity pretends the physical object isn't there, and just clips right through it. This is most likely like this by design, but for Vectronic it was a huge issue.

 

The advertised way of doing platforms is to use the Joint class so the entity will have mass and interact with other physics objects. However, the Vecboxes need to be heavy, I'm talking about setting the mass to 80 to prevent the object from bouncing like a kickball. Increasing the overall world gravity effects the player, and I want the box to be lighter when it's activated by the 0g Ball, which makes it easier to throw. Problem was that if a box was to go on these platforms with the mass I need them to be, the box would overwhelm the joint, and break it.

 

Platforms is something I see important to the project as by now (in the earlier puzzles) they are used for demonstration of how the 0g cube works, and are in the majority of maps I have already made. If platforms can't work, I was afraid I was back on the bus of looking for another suitable engine for the game. Luckly Einlander came to the rescue and set me something that worked better than all my other attempts.

 

Einlander's script moves the object from it's resting point to another position similar to the sliding door script. It also updates it's Physics Position and Omega in a function called in UpdateWorld. The result was exactly what I want minus a slight jitter in the box, but I'll take it. After experimenting with it though, I noticed that if a box was only partially on it, the platform would ignore the box, and go right through it; a similar problem I kept having. My fix was to create a trigger that's spawned with the platform with it's shape to handle this case, and behavior with the 0g cube. It's still not 100% perfect, but it's better than what I had before. The project was now back in gear.

 

Another concern I was having was questioning "How much fun is my game, or is it just work?". Running around, shooting power balls at boxes so they change their properties sounds like a good concept on paper, demo maps, but imagine a full 2 hour game of just that? I was worried that just focusing on that would get really boring; so boring that it might even make people to stop short and refund the game.

 

As if it was not clear already, Vectronic is a tribute to Portal as if it wasn't for that game, I would not be here talking to you right now. I started to think about Portal, and I started to look at it from a weird light: How would Portal be if momentum (Flinging) wasn't part of the game? There are five chambers, and the BTS areas that require or focus on using Portals to fling over gaps, and a good chunk of code is dedicated to make sure the momentum multiplies when going through each portal until the player or object hits it's max speed. But imagine if the game didn't have it, you'd have a game where you walk into walls to move mostly boxes around. Again, this might not seem so bad, but imagine playing it for 2+ hours with only the original elements; it will be similar to what I have now with Vectronic.

 

The issue I think is the lack of Player Mobility. From my observations, people like to use their weapon to get to an extreme height. Join any Team Fortress 2 server and you'll see Soilders and Demomans blast jumping, and Scouts double jumping everywhere. With PUNT had something called Punt jumping which was like Rocket Jumping, but you could only do it on certain materials. From the feedback I got, people were most excited about that. Only issue is that it required skill, and it was never fully taught.

 

I'm currently experimenting with this bounce jumping idea. Imagine rocket jumping only on certain materials, but all you need is to double tap Space. I've got only one map done as a proof of concept and to introduce the idea to others to see if it worked. Two days ago, I shipped the build early while this was still being figured out to see if it was worth the effort. I got a positive vibe from their feedback, I got told it was fun, although they didn't fully understand how to control it. Regardless, this might be because I was calculating how high the jump should be based on the time you're falling, not the speed, but it shows that it's not perfect yet.

 

I should have more information about it next week (hopefully!). I want to go back and forth with my pre-alpha testers until it's a fun and fully understandable mechanic.

reepblue

Experimentation

I almost let a whole week go by without writing a blog, ahh! I've been doing a lot of thinking and experimenting over the last few days, and talking to other people about Vectronic.

 

Last week, I talked about improving functionalities of the pickup system and the platforms. Although the pickup system is near done, the platform system, well they need work. I made a topic about them here, and kind of left me on a stand still on the project because I see them as a vital piece of the game, and they need to be perfect 100% of the time.

 

As I mentioned before Vectronic always seemed to feel and play like a demo. there was never more than 3 maps, and the ideas were very basic. The method of slopping out maps quickly, and fine tuning them later is fixing that as there are way more maps than ever, but unfortunately I'm noticing a problem with the actual core gameplay itself, something I would never notice with just a few demo maps.

 

It seems as though although the box has cool effects attached to them, they mostly need environment elements to really make them shine; which is a problem. The question is, is it the powers attached to the balls, or is it that the balls can only activate the boxes. And if the balls can activate other elements, how would they work, and what problems would it solve? I went back to the project what Vectronic morphed out of to see if those ideas can fix problems that Vectronic has.

 

 

In the old project, the power was tied to each box, and the player would fire electric bolts at them to activate or deactivate them. I had a cube that reversed it's gravity, (Along with other cubes because I didn't know how to make it so only THAT cube flipped) one that stayed static in the air, a cube that exploded, and a cube that did nothing at all. This method had problems, which I talked about here.

 

The idea of the flip cube was something I really loved, but I couldn't figure out how to only make that one cube reverse gravity while the others remained normal. Out of curiosity, I decided to quickly script this cube and simply have it flip when the F key was pressed. I got the effect I wanted, but it's not flawless. what I did was when the cube was told to flip, it would use a joint to go to the ceiling. You can ride it up, but the player would clip through the ceiling which I think I can fix on the player side, and you can't pick up a box when the box wants to go up; but again I think I can fix that.I also have ideas on how to make the ghost cube more fun and interesting.

 

But then comes the question is this really a problem, or is it just me working on an idea as a demo for such a long time that I find it boring? I'm asking a lot of people for input and one person plans on give me a playable prototype of his idea so I'm looking forward to that. I want Vectronic to be the best it can be, and if it ends up being different than the demo or what it ever was, but a lot more fun, so be it.

 

Besides gameplay, I've also been playing with tolua++, and getting ideas what I wish to do with LEX in the future. There is also the Halloween Game Tournament so maybe my head will clear up when I'm working on that. There have also been some experimentation on art, but I'm not ready to talk about that yet.

reepblue

Besides fixing the UV's for the VecDispenser, Adding in the box model, and some added sounds thanks to ThirstyPanther, most of the work this week was done with adjusting scripts so that the game as a whole plays better.

 

 

Picking Up Objects

 

Last week, I mention that I adjusted the pickup system so that it will auto center the object when it's picked up. While the stock code for the pickup system is good for occasionally picking up objects, in Vectronic, you're gonna be picking up boxes a lot. Not only that, but some puzzles require you to throw the boxes straight a head. The stock code locks the position and of the pickup with the picker position point which produces results like this.

 

shot10.png

 

The pickup system needed to feel natural as possible. I wanted the object to tween from the current location to the center of the player's crosshair, much how the pickup system is in Source. It only took an additional transformed point from the camera, and using Math:Curve to translate the two positions together. The box position will always now be centered with the crosshair when picked up.

 

shot9.png

 

This fix caused a few more problems which I'm still tweaking, I've added collision back to the picked up object, prevented the player picking up the object if they are standing on it, and also made the player auto drop it if the speed of the object is going too fast due to movement speed or violent collisions. It's not perfect now, but I feel that it's better than the stock pickup system, at least for this game.

 

 

Platforms

 

Another fix I've made is with the moving platforms. One major I've found with the sliding door script is that if a heavy object is on the joint object, the joint will fail, and fall through the floor. Since the boxes need to be heavy so they don't bounce really high, I felt like this was not a good system for the platforms.

 

In the demo, I've made a script that just moves the model's position over time, but further playing with this script showed me that there was issues actually pushing the player up, while jointed objects did not have this issue.

 

So I went back to the sliding door script with the problem of heavy objects effecting them, but lifting the player is fine. I solved this by making the joint object invisible and it's collision set to only collide with the player, and nothing else. Then, have the platform model as it's child which collides with everything else. This solved both problems as heavy boxes don't screw up the platforms as it's not colliding with the platform, but the player and objects can ride with the lifts without any issues!

 

shot11.png

 

I still need to work on a better way to set the distance, as right now you have to guess and tweak the distance values which I don't seem to like very much. I plan on switching it to a location point instead. Overall, the platforms need to be more user friendly as right now it's just a modded version of the sliding door script. I might work a bit on that this week.

 

I'll continue to work little by little to get everything as solid as I can. There is also a map in this set that I feel that's not as fun, informative or needed that I want to adjust or replace before working on any new maps. The goal is to get all this basic stuff perfect before continuing.

reepblue

First Test, VecBall Design

Another week, another weekly report. Vectronic is going more smoothly then ever before taking things one at a time, and just shelling out maps and ideas quickly. Last week, I did a few improvements with how the player picks up objects, and fixing the issue of shooting projectiles through objects. I did not shell any more maps because I thought it would be better to focus on a small amount of puzzles at a time, perfecting them before making more maps. For this, I needed help.

 

As of this week, I quietly put the first test build on in the Dropbox folder which used to host the Source build, and asked a small number of people to test out movement, mouse control, and if everything feels right before I make things more complex.

 

From the first week of testing, I'm confident that the project is moving in the right direction. From one tester who has played all other builds of Vectronic told me that this current build has better puzzle direction and clarity, and full of gameplay unlike previous builds that was just a bunch of mechanics, pretty rooms, but no gameplay at all. I got recommended a few changes I should make, like making the box heavier so when it crashes to the floor after floating in the air, it does not bounce off a button, or adding a plane of glass to block a more frustrating solution. A few tweaks still need to be made, solutions should just work, and not fully relying on the physics engine. I recall this being a problem with Quadrum Conundrum.

 

Word of advice though, I learned that play testers hate fully ambient lit rooms, so before you release for testing, atleast put fill lights in. One tester told me it was hard to perceive the room with a full ambient light. I have one map with fill lights as a test, and he reported that when he got to that map, he had a better experience.

 

I also found out that this method on leak protection didn't work when you packaged your games. It failed to initialize Steamworks although Steam was running. Not sure if this has to do with how packaged games work, or something I did wrong. I could of just uploaded the raw project, but that's a difference of 88MB vs 18MB. I'll work on this for the next build which I plan on posting a new test build biweekly.

 

VecBall Design

 

Yesterday, instead of writing this blog post, I was in an art mood, and wanted to put something back online with a model and sounds. I was using the old ball sprite and particle effects from the Demo, and I was really unhappy on how the dispenser looked in Leadwerks compared to how it was in Source. I decided if I was gonna touch anything art related, it was gonna be the basic foundation of the Vecballs themselves.

 

I already had an idea of how I wanted my balls to look in the previous build. I'm a huge fan of how the Portals where in Portal in pre-release builds, and I wanted to reference that.

 

lvl7_x060000.jpg

 

This portal design required a large amount of textures for the mask, overlay, and other things that portals need. These portals took a whopping 174MB of VRAM PER PORTAL. and this was 2006/2007. I'm told that Valve cut it only because they ran out of memory on the Xbox360. Besides them being memory hoggers, I'm happy that I have them in a mod where they work exactly like how they did in previous builds.

 

Unlike Portals, I can do a sprial/swirl effect with my vecballs without going over budget. I really liked the idea of the balls being a swirling ball of energy, so this could work. I made a quick texture and effect before I focused more on LEX. I later put what I've did in the Vectronic Demo.

 

I pretty much just copy and pasted my swirl edits I had before into this build with a few changes. It still needs work, but it's pretty much the same as it is in the Demo, at least for now.

 

devtest0001.jpg

 

Now to the dispenser. What makes Vectronic diffrent from Portal is that you loose your vecballs after each level, requiring you to recollect them in the next map. When I first sat down for the design of the dispensers, I sorta saw them as the item pickup bases in multiplayer games like Unreal Tournament. In Source, the particles stood tall and really stood out. But when I was transferring the design to Leadwerks, no matter what, they appeared washed out. This might be because of the colors, but I could not replicate how they appeared in Source.

 

So I decided to take the dispenser back to the drawing board. I felt that the bases were too small, and needed a face lift. I quickly made this out of a cylinder in blender, added some base colors, and called it a day. UV sheet is still bad though, something I always have problems with.

 

shot5.png

 

Attached a few emitters and sprites to it and got this in-engine.

 

shot6.png

 

This is still not final as the ball sprite can still get washed out in the environment. I'm not gonna worry about it until I start messing with post processing effects and the overall look of the maps. I'm also open to suggestions. It's good for now, and it's a hell of a lot better then how they are in the demo!

 

So that wraps this weeks report up. I guess this weeks goal is to ask more people to test the seven maps I have and seeing how I can improve those and other things before moving forward.

reepblue

Shelling It Out

As I mentioned in my previous post, throughout my time of developing Vectronic on the Source Engine, the project never had more than four maps because so much time and worry was focused on the concern of how it's going to look. While the overall art style, and the balance of visual noise is importation for a project like this, I was spending more time on this than making more maps and puzzles.

 

I decided to once again start from scratch and only focus on the maps and gameplay for the time being. With this mindset, I've gotten close to seven maps shelled out in dev textures, placeholder models, and no lighting. On top of those seven maps, I've got two more ideas down on paper. With this method of developing, perfecting the how the elements interact with each other is much easier to do.

I can easily change a puzzle, or how a puzzle is solved if something ends up not working the way I intended it to, without moving a handful of models and lights.

 

shot2.png

 

As you can see, there is only a white ambient Light being used, Doors just appear and disappear, and platforms use the Sliding Door Script. Things are coded to be as simple as possible in this era of development. I even made the two ball colors primary red and blue for simplistic identification. As I said before, if the game is fun like this, It's only going to get better from here!

 

shot3.png

 

With how fast maps are moving, additional elements that were not in the demo were needed quicker. And the new puzzle elements such as trip lasers and ball launchers only have basic functionality built in to not slow down the development of new maps. If something needs to be tweaked, it can easily be done with little worry of it breaking something else. The elements are being developed with the maps that use them, not in some zoo developer map with code that might be needed like I've done before.

 

I'm making it so that each idea is it's own map. Although the engine would be able to handle a few rooms in one map, puzzle games are different then story driven games. Puzzlers need to be perfectly balanced. If you introduce something too soon, too late, or too many new things at once, the learning curve will not be well, a learning curve, and you can overwhelm, or bore the player. Having each idea or puzzle tied to one map, I can easily switch the order, cut out, or add in maps in-between without much headache. I might combine maps when the order of them settle in the future, but it might just be the really small ones.

 

shot1.png

 

I've currently been making maps in order of progression, but I think in the future, I'm just going to make puzzles not worrying about the order of progression, and workout how (or if at all) they'll fit in the game. My goal is to get ten or fifteen maps done before I even think about how everything is going to look. At the rate I'm going, I should be back in Blender and Paint.net by next month! I have ideas about updating the visual style, but nothing I plan on talking about yet.

 

Sorry about not posting this article Friday like I said I was going to. I want to write a development blog weekly for my sake of keeping me motivated, so expect at least that.

reepblue

Back On Track!

After a whole summer of working on the LEX template, and learning new things about the engine, I'm happy to say that Vectronic will soon be back on track in full development!

 

Before I go into full detail, I wish to mention that the Vectronic Demo has been updated with Josh's optimization edits, and the VecBall has a new effect I've made during the development of LEX. If you had sluggish performance before, I recommend you check out the update!

 

Now that I've got a nice foundation with a menu, a precache system, now what? I was thinking I would just be "upgrading" the Vectronic project to use the LEX template, but looking back on it, I'm not really happy how it is. Back in May, I really just ported textures, sounds, and models from my Source build to Leadwerks to see if a game like Vectronic would work on Leadwerks. Of course, I was still pretty new to lua scripting, and very use to pre-built lighting and such so I did struggle a bit, the demo map was not optimized, and most of my code is a mess. To wrap it up, I mostly did not know what I was doing. I still to this day see that demo map as a map from hell; I've had so many issues with it, but I'm happy how it turned out.

 

Now 6 months later, I feel like I've learned a lot and ready to get back onto my main project again. I decided the best way to start is to start a new project based off of the LEX project, and redo most things. I've restarted this project many times over for the past few years, but this should be the last time.

 

Back when I was developing this project on the Source Engine, I've felt like I needed assets to make a game. I thought if I had everything, textures, models, sounds and other assets done, I could build levels like a LEGO set; having all the pieces, and knowing where everything goes. It's a good theory, but it never really worked.

 

punt_a_000002.jpg

A old Source build of Vectronic.

 

I only had a few maps per build. The last build had 3 maps, and the build before that had 4 maps. There was never a set of interesting and fun levels, just a

. Thing was, I was so worried about how things functioned and looked that no build ever got more then a few maps, I was distracted by other things that are not important in the pre-alpha stage of things, and so were my testers, which did not help move the project further ether..

 

Learning from my mistakes, this time the project is going to start blank almost like the past few years never happened. Doing the reboot this way will force me to worry about scripts, and the actual puzzles. This will also make it easier to optimize the maps when it is time to bring in the assets, and not have what happened with the demo map. No lights, no models, just CSG and a few scripts. If the game is fun with just that, it's easy sailing from there!

 

Now, that does not mean I'm gonna waste more time by re-scripting, re-modeling, and re-texturing things that are already done. There are somethings I think that can be better, and I do have ideas I wish to try, but not everything needs to be scrapped, somethings just need a revision. I eventually want to give Vectronic a look that only Leadwerks can give as the demo does look like it's running in Source. But right now, the basics need to be done!

 

I hope to update every week on progress, I'm feeling this Friday I'll talk more about how I'm doing things and short term goals.

reepblue

I recently updated the Leadwerks Extended Executable with more shaders, and hot fixes. Fetch and pull this update in git. I wanted to post this yesterday, but I was having issues.

 

Fix 1: No more crashing upon Alt+Tabbing

This fix is eventually gonna be made engine side, but I was not sure if Josh plans on that being pushed to the default branch, or the beta branch. While the beta and default branch are synced, I jumped the gun and fixed it.

 

 //---------------------------------------------------------\\

// This will be fixed engine side in a future version of LE.

// For now, we are gonna apply this patch.

if (window->Active())

{

// Update the world.

world->Update();

}

 

if (window->Minimized() == false)

{

world->Render();

}

//---------------------------------------------------------\\

 

2: Fixed saving conflict between the options and advanced options panel.

Before I went to bed last night, I noticed that if you edited a property on the advanced panel, then edited a property on the options menu, the old value you just changed on the advanced panel would reset. This has been fixed by reloading the xml file before it saves values.

 

3: Fullscreen mode will now always get the current display resolution.

In the initial release, the application would get the size of the display and store it in the settings.xml file. Although this was a good idea, I realized that this could be bad as a display can change if the user want's to play your game on his 1080p TV while they have a 900p monitor. If fullscreen is enabled, it will now ignore the resolution stored in the settings file, and just fetch the current display size from the System. The screenwidth and screenheight properties are now only used for windowed mode.

 

4: More Shaders!

I've added animated versions for the color-emission, cubemap, and detail model shaders.

 

I'm currently working on some documentation for this, and will update the opening post of the tread with Google Doc links to them. I've also set a Trello board for this so you can see what's next on the list for this project. Hopefully it will not become a wasteland like my Vectronic Trello.

 

Although I feel that this is solid how it is, continue to add your input and suggestions.

reepblue

Leaks of games happen, and they still happen. You can spend months and months working on your game, only for a server attack or the wrong person to share it with their buddies; which then goes public accidentally, (or intentional). Having an unintended work in progress build out there can give people the wrong idea about your game because there are people out there who think the development process is pretty straight forward.

 

Let's take a look at the Half-Life 2 leak. The game, and the entire engine code was leaked and the entire thing was very unstable, It was also found out that all those

were scripted, and broke when you actually play them. A lot of doubts and concerns about the game were made as they felt like they were lied to after seeing videos and screenshots not representing the leak at all. Of course, this later on generated a community of it's own, but that's a rare scenario.

 

Since Leadwerks is far more stable than a Source Engine build from 2003, you can have months of playable work leaked. If you indeed plan to sell your game on Steam or Desura, you most likely don't want you're game freely available. So how can we prevent this?

 

If you already got a SteamAppID from Valve after a successful Greenlight campaign, there is nothing to worry as users need a key to access your game. But what about if all to your game is dev textures, rough code, and programmer art? If you only have the indie edition, or only use Lua scripts for your game, you can use the Game Launcher, and set your game to "Friends-Only". For games written in C++, or have a modified application, we can't do that as our program does not get uploaded to the workshop. With the Standard Edition of Leadwerks however, we can use more of the Steamworks API.

 

A friend of mine was talking to me about how an old Source mod use to detect if an invalid Steam user tried to boot the mod, it would not boot. Once I heard this, I was eager to see if I could get a similar system to work.

 

Every Steam user has a public unique ID that comes in many different forms. Steam and games use this to gather information about the user, among other things. In this case, we are going going to focus on the 64bit FriendID number. Thanks to the Leadwerks API, we can access Steamworks features without our game being on Steam!

 

Let's us first start with creating a bool function under the main.cpp.

 

bool CheckSteamID()

{

if (Steamworks::Initialize())

{

}

 

System::Print("Error: Failed to initialize Steam.");

return false;

}

 

So far so good! We make it a bool function so if we are not a fail to load Steamworks, or have the wrong ID, it will return false and close the program. Now let's get the users ID number with:

 

uint64_t user = Steamworks::GetUserID();

 

As I said before, SteamID's come in various forms. The easiest to get is the 64 bit FriendID which appears in profile urls such as http://steamcommunity.com/profiles/76561197996502882/

 

As you can see, my SteamID is 76561197996502882. For the rest of this article, I'm gonna use mine in place of where you should put yours. A way to get yours is to go on a site such as http://ihavenfi.net/steamid. Popping in the STEAM_0:0:******** format after putting your ID-less profile URL will give you your FriendID. Remember, these numbers are public, they aren't like credit card numbers, or anything.

 

So let's continue! For this example, I'm going to use My SteamID. So let's make a simple if statement comparing the account trying to play this game with a hard coded value.

 

bool CheckSteamID()

{

if (Steamworks::Initialize())

{

uint64_t user = Steamworks::GetUserID();

if (user == 76561197996502882) // Me!

{

return true;

}

else

{

System::Print("Error: Invaild SteamID!");

return false;

}

 

System::Print("Error: Failed to initialize Steam.");

return false;

}

 

With this code, (and I hope you replaced the SteamID), your game will only work for you if you're logged into your account. But you need beta testers, and what about the other developers? Let's Continue by adding more IDs!

 

As another example, let's grab Josh's SteamID. After all, he's the CEO and should be able to play any LE game he wants. wink.png Although his profile is private, we can still grab the ID-less URL which is: http://steamcommunity.com/id/JoshKlint

 

Pop it in the converter and we get: STEAM 0:0:6085996. Let's pop that value in again and we finally have his FriendID which is: 76561197972437720

 

Now let's edit that if statement.

 

if (user == 76561197996502882 // Me!

|| user == 76561197972437720) // Josh

{

return true;

}

 

Now, Josh can play our game if he's logged into his Steam account. The best way to get ID's is to make a Steam Group for your testers this way you have all the profiles listed that you need to code in. We're not done yet, we still need to call this function near the start of the main function.

 

if (!CheckSteamID())

return 0;

 

Just make sure you comment that out when your game does get to be on steam, or when it releases elsewhere with a different DRM measure if you desire.

 

With this somewhat messy way, you can restrict your games to certain steam accounts without having your games on steam during development. As a bonus, let's welcome the user in the console to make the tester feel they're special. Put this before the function returns true.

 

std::string username = Steamworks::GetUserName(user);

System::Print("Hello there, " + username + "!");

 

And that's it! There is most likely other ways of doing this, but this way is the simplest and easiest. If you hard code FriendIDs, and use the stand-alone publishing for beta builds, your game is just a bunch of unplayable bites and bits if it falls into the wrong hands!

reepblue

After the release of the Vectronic Demo, I started to seek out how to make the game to be able to stand-alone without any additional launchers, batches, or required installations. Shortly after my last blog post, Josh informed me about Inno Setup, and it answered my questions about providing OpenAL if the user did not already have it installed. More about that here. I haven't played with it yet, but it gave me insurance about packaging it up for the final release down the road. Alternatively, Steamworks is also an option, but I'm not touching anything Steamworks related until I get a App ID for the game.

 

With the Leadwerks Game Launcher, users can edit basic settings such as "Resolution" and "Fullscreen" and any settings that may come in the future. As a stand alone game, it would not have easy to use game launcher, hence a menu with a settings feature is required.

 

I didn't want to make a launcher, as they are kind of unpopular, and OS exclusive. (You'll have to build a launcher for each platform.) I wanted something already in the application, and can be compiled on multiple platforms minus a few edits here and there. I also wanted most settings to be real time so players can adjust their settings to their likings without needing to restart the game.

 

800px-Ep2_menu.jpg

 

One thing I really liked about developing mods for the older branch of Source was the gameui system it had. It was simple, reusable, and out of the way. You could edit the res files to customize it if you wish, but it's stock files was enough to get you started; even release with. I wanted my UI to be based on this. Only reason why they retired this UI system in favor of their hell of a client based UI system starting with Left 4 Dead, (I played with it, it was not fun) was due to Console/Controller support. Yes, the Xbox360 controller does work in the old UI, but when you open it's panels, you better have a mouse near by!

 

However, with things like the Steam Controller, and the fact that Leadwerks is mostly PC based anyway, this UI design will certainly do.

 

To make it reusable, the UI would have be modified outside of the source code. Changing fonts, colors, titles should not require a recompile. Also, such things like the start map, and background map should also be able to be changed outside of the source. No matter what game it is, it should work.

 

Finally, to make it out of the way, the entire system would be written in C++, and not interfere with any game logic written in Lua. However, from Lua scripts, you should be able to communicate with it in case you wish the application to disconnect you from a map, or shutdown the application entirely. From lua, you should also be able to grab boolean states like if the app is paused, connected (in-map playing) or disconnected, and not in any map if needed.

 

So that was the goal, and 3-4 weeks later, the goal was completed with a few bonuses such as a precache list for loading models/prefabs onto memory, a very basic save system, and in dev mode (which is also enabled in debug mode), information about what version of the engine you're running and map name is printed in the top right corner when paused. (Something Source does which I liked.)

 

Screenshots_screenshot9.jpg

 

Screenshots_screenshot10.jpg

 

(Could not use media tags due to them being Unlisted)

 

I'm very happy of the results. Not only this necessary element for a stand alone is done, but this will make my testers happy as they no longer need to edit batch files to configure their settings! I believe that this is necessary, and anyone should be able to have it. After a few more bug fixes, I'll upload the Source files to GitHub along with application releases so even people with the indie version can use it.

 

Only thing I did not test was the application on Linux since the hard drive in my Linux machine finally died after 7 years of service. Knew it was coming, but still a set back. Hence another reason why I want to make it public, so that it works on all supported platforms and gets more optimized over time. I'm not the best programmer in the world, so every little thing helps!

 

I'll talk more about this when I put it up. There is a lot of technical stuff about it,

reepblue

Over 2 weeks ago, I released a small demo showcasing my project's core gameplay on the Leadwerks Engine. Although I'm happy with the demo; it's a good landmark for the project, but it can be better visually and functionality. I learned a lot of new information about the engine on how to better optimize it, multiplatform diffrences, and I grew a slight hatred to a certain brand of GPUs. But the demo on the Game Launcher to me was a success.

 

The stand-alone version in my opinion was a bit shakey as with stand-alone releases you lose the end user's ease of use when it comes to settings and the requirement of OpenAL. The Vectronic Demo was indeed targeted to work with the Game Launcher from the begining as I wanted to be more focused on the actual game scripting than the dirty stuff such as how settings are loaded, menus, etc. But I also wanted a stand-alone version out due to the launcher being in beta, and I wanted to let people on linux play it.

 

I took Vectronic to the Portal community to see how they liked it. I mostly got back issues in actually launching the application. Besides the lack of OpenAL, most people did not seem to understand how they can run the Portal 2 (Which runs on a branch of the Source Engine that can run on DX9 cards.), and other games but not Leadwerks; especally on a certain brand of a GPU. One person actually got angry at me because he could not run the game. Overall, it was mostly things that Josh nor I can fix. (i.e it was ether outdated hardware or poor drivers.) However, the OpenAL requirement is something I can look into.

 

Right now, I'm stepping away from the demo, and focusing on improving the stand-alone experience now since the soultions for the standard edition has been recently optimized. With the Summer Games Tournament coming up, it's a good deadline to stay focused, and to experment with non-Vectronic stuff. After this project is done, Vectronic will be back on track as I kind of need this done before I continue to work on my main project.

 

I still got Part 2 of My Introduction Entry to write which I share why and how I moved the Project to Leadwerks, but I think I'll write that when I want to look back as right now I want to looking forward. I might also share various techniques I used in the Vectronic Demo as I think it will help with any user of Leadwerks; especially durning the summer tournament. I'll continue to write about whatever I'm working on here. :)

reepblue

Note: This is pretty much a copy and paste from this post here with a few tweaks.

logocropped1.png

After 3 years of planning, modeling, texturing, and a lot of engine hopping, I was able to create a playable demo in the Leadwerks Engine for Windows and Linux (Debian/Ubuntu/Mint). You can download the demo from this page. A small demo was created not only to test the basic elements of the game in the new engine, but to also give back to those who have been supporting this project since I started talking about it.

 

2015-05-23_00001.jpg

 

2015-05-23_00003.jpg

 

I'm also announcing that from here on out that the development will be more open. How open? Well first you can always check the Trello page to see the progress at any time, If you wish to help, drop me an e-mail. Feed back is welcomed with opened arms. You can do this simply by e-mail or twitter @reepblue. I'll do my best to respond if necessary.

About Vectronic

Vectronic is a first-person environmental puzzle game inspired other games of the same genre such as Portal, Quadrum Conundrum, and Q.U.B.E. Players must solve puzzles using special power balls that effect boxes that changes their behavior in the world. For more information, please visit the Q&A. For additional help, click here.

Please let me know what you think. Although a short primitive demo, this is a big milestone for the project in the indie path.

reepblue

Hi,

 

I've been reading and posting here and there on the forums for quite some time now, and being that my current project is taking shape, I think it's time that I introduce myself, and in the next post, I'll share some goals of my project.

 

Quick Bio:

 

As a Kid, I've had an interest in game development with my hundreds of hours I put into RPGMaker 2000/XP. At that time, I was mostly inspired by The Legend of Zelda series and other top down games that could be made in the program.

 

When I was a young teen, I was not really into PC games. I stuck to my old Nintendo consoles while my brother would play Counter-Strike: Source on a daily basis. I remember him once showing me a custom map he made for CSS that be based off our local 7-Eleven store. He was showing me how he made the textures, and a bunch of other simple things. I can't recall if I was blown away, or wanted him to stop talking so I could do my thing to be honest.

 

After a while, my interest in game development started to fade, and I got more into graphic design for websites and such. But then game called Portal. I was not into first person shooters, but I did like Puzzle games, and this game was one of a kind when it released. My brother got The Orange Box package and I played the living hell out of Portal. The game was so interesting to me and there came a point where I would turn on cheats, take the metal rectangles, move them into position, and save the game. Then a "custom puzzle" would be loaded like loading a saved state.

 

And it begins!:

 

To make a long story short, I eventually got The Orange Box for the PC, got a budget build, and made a lot of maps that never got released. Portal 1's gameplay elements where just a collection of base engine entities that worked together. I spent months on end learning how to make breakable glass, the indicator strips, buttons, doors, you name it! After I felt like I had enough knowledge of map making, and the I/O system, I decided to work on my first mappack called Blue Portals.

 

 

bp_2008-m20004.jpg bp_2008-m50009.jpg

 

The project was on and off. I was working on another project at the time, so these maps were totally remade from the ground up with a new art design.

 

bp_020000.3.jpg bp_090000.jpg

 

Through out the years and other side projects, Blue Portals was released on November 29th, 2010. The mod got mix reviews, and looking back on the project, I can say that it's not for everyone. But I can say that it does have a cult following.

 

With the release of Portal 2, of course I was excited to work on custom maps. I first started to to work on a Blue Portals 2 to fix the flaws of the original, and to add other cool elements. But due to the different FileSystem structure of that branch of Source, and my lack of knowledge of it at the time, I canned it. It was a good thing too, because DLC1 made the unused Adhesion Gel weird which BP2 used.

 

I've made some small mappacks such as A Little Higher, Tornate, and Feather Away. I also worked on most of the test chambers for Alive & Kicking while I was making new game concepts still within the Source Engine. After a while, Portal started to get boring, and the second DLC for Portal 2 (PTI) made me lose interest in making Portal puzzles because now anyone could do it, and it killed the art for me.

 

I started a project in the Source Engine called Punt and to sum it up, it was me trying to find what I want as my own puzzle game.

 

 

 

After a while, I got the gist that the main core concept of the Puntgun was not fun. That, and the code base was a mess due to the Puntgun being a mod of the gravitygun, and poor tracer code. Also, Valve released a new SDK base to replace the one from 2007, and I really wanted my mod to be less like Portal gameplay wise.

 

In the next entry, I'll talk more about my project, the goals and why I decided to port it to LE3.

 

In the meantime, you can checkout my Youtube channel to see what I've done throughout the years. (I hope to put Leadwerks related content on it soon!)

https://www.youtube.com/user/reepblue

 

And here is my blogger which as more of my writings and thoughts:

http://reepblue.blogspot.com/

 

Thank you for reading/watching. I hope you are willing to hear more!