Jump to content
Entries in this blog
The beta branch on Steam is now updated. Version 4.6 introduces peer-to-peer multiplayer capabilities with a new multiplayer game template. Check out the new features in the documentation:
The physics library is updated to the latest version of Newton.
The editor has some enhancements as well:
Model editor view range is calculated from model extents, so if you load a model that is huge it won't be invisible.
Model editor displays number of limbs as well as vertices and triangles.
Settings file is now saved any time changes are made in the project manager or the options editor.
Menu added for Leadwerks Marketplace. Paid Workshop items are no longer accepted.
Menu item added for Discord chat.
Please test this out and report any errors in the bug reports forum, as this is pretty close to the final version 4.6.
Here's a look at the new vehicle system that is being developed. The API has been simplified so you simply create a vehicle, add as many tires as you want, and start using it. The AddTire() command now accepts a model and the dimensions of the tire are calculated from the bounds of the mesh.
int AddTire(Model* model, bool steering=false, const float spring=500.0f, const float springrelaxation = 0.1f, const float springdamping = 10.0f);
void SetGas(const float accel);
void SetBrakes(const float brakes);
void SetSteering(const float angle);
static Vehicle* Create(Entity* entity);
A script will be provided which turns any vehicle model into a ready-to-use playable vehicle. The script searches for limb names that start with "wheel" or "tire" and turns those limbs into wheels. If they are positioned towards the front of the car, the script assumes the wheels can be turned with steering. You can also reverse the orientation of the vehicle if the model was designed backwards.
There is one big issue to solve still. When a vehicle drives on flat terrain the tires catch on the edges of the terrain triangles and the whole vehicle bounces around badly. I'm looking into how this can be solved with custom collision overrides. I do not know how long this will take, so it might or might not be ready by Christmas.
I'm wrapping up the new multiplayer capabilities for Leadwerks 4.6, and I am very excited about what this offers developers.
We saw previously how the lobby system is used to create or join games, and how to retrieve Steam IDs for messaging. Once we have joined a game we can start sending messages with the P2P::Send command, which includes a few overloads:
static bool P2P::Send(uint64 steamid, const int messageid, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, std::string& data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, Bank* data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, Stream* data, const int channel = 0, const int flags = 0);
static bool P2P::Send(uint64 steamid, const int messageid, const void* data, const int size, const int channel = 0, const int flags = 0);
Each message has an ID and can be followed by additional data in the form of a string, bank, or stream. Voice chat is handled automatically, but the rest is up to you to decide what data the messages should contain. I provide examples for text chat, joining and leaving a game, and movement.
Receiving messages from other players is extremely simple:
static Message* P2P::Receive(const int channel = 0);
The message object has information contained within it:
We can evaluate messages based on their ID. For example, here is a text chat message being received:
auto message = P2P::Receive()
if (message->id == MESSAGE_CHAT && message->stream != nullptr)
A new multiplayer game template will be included, with out-of-the-box support for text and voice chat, public servers, and player movement.
You can download the test app and try it out here:
Thanks to everyone who has helped me test this!
After using it for a few weeks, I previously deleted our Discord server for the following reasons:
Community activity was being taken from our site to Discord.
They weren't really providing anything of value.
There have been some problems with our Cometchat integration lately. I have noticed new messages are not popping up like they should, and selecting the link to view a user's profile does not work. So I set to fixing these issues.
Upgrading CometChat to the latest version my account has access to did not solve these issues, and it introduced a new problem where the chat bar was not being hidden when the user logs out.
The company has changed their pricing to a much more expensive subscription plan. With minimum features I would be paying $50 monthly, and I still don't know if these issues are fixed in the latest version.
More expensive versions also support audio and video chat, but in the last when I have tried these they have always been dodgy. In order to add support for these additional features, which I don't know have improved, it would cost $99/mo. total.
At this point I decided that Discord is in fact providing a valuable service for us and I am going to rely on it from now on. Our built-in chat system is now disabled and I encourage you to join me on Discord. This time it is here to stay:
The next update will include a new networking system with built-in voice chat for multiplayer games.
Voice communication is built into your game and can be enabled simply by turning it on when a specific key is pressed:
You can selectively filter out users so your voice only gets sent to your own team or to a specific player:
void Voice::SetFilter(const uint64 steamid, const bool state)
When another player sends their voice data to you, the engine will automatically receive and play the sound. You can also retrieve a sound source for a specific player and make adjustments to it. This can be used to enable 3D spatialization and position the sound source where the player is, for VR voice chat.
Source* Voice::GetPlayerSource(const uint64_t steamid)
When I first implemented this the sound was sometimes choppy. I added some automatic adjustment of the pitch to slow down the sound a bit if new data is not received yet, and to speed it up if it falls too far behind. This seems to work really well and I'm sure it must be a common technique in applications like Twitch and Skype.
A new multiplayer game template will be provided that shows how to set up the framework for a multiplayer game. Here's a video preview of the voice communication in action.
The new Lobby system in Leadwerks 4.6 allows you to create a public listing of your multiplayer game for others to join. This uses the Steamworks library. You can tap into the Steamworks lib by piggybacking on the default "SpaceWar" example game, which uses the Steam app ID 480. This is set up by default when you create a new Leadwerks project.
Now you might think of a lobby as a place where people hang out and chat before the game starts. You can treat it like this, but it's best to keep the lobby up as the game is running. This will allow other people to find the game to join, if it isn't full or if someone leaves the game. So a lobby is better described as a publicly advertised game others can join.
Creating a new lobby to advertise our game is easy. We just call a command to create it, and then we will set two string values. The game title is set so that we can later retrieve only lobbies that are running this particular game. (This should be done if you are using the SpaceWar app ID instead of your own Steam ID.) We also add a short description that can display information about the game.
Lobby* mylobby = Lobby::Create();
mylobby->SetKey("description", "Here is my lobby!");
It's also easy to retrieve a list of lobbies:
int count = Lobby::Count();
for (int i = 0; i < count; ++i)
Lobby* lobby = Lobby::Get(i);
We can use GetKey() to look for lobbies that are running the same game we are:
if (lobby->GetKey("game") == "MyGameTitle")
We can retrieve the owner of the lobby with this command that will return a Steam ID:
uint64 steamid = lobby->GetOwner();
Once you have that Steam ID, that is all you need to start sending messages through the new P2P networking system. More on that later.
And we can also retrieve a list of all members in the lobby:
int count = lobby->CountMembers();
for (int k = 0; k < count; ++k)
uint64 steamid = lobby->GetMember(k);
After a lobby is created, it will have one member, which will be the same Steam ID as the owner.
Joining a lobby is simple enough:
if (lobby->Join()) System::Print("Joined lobby!");
And leaving is just as easy:
Now here's the magical part: When the owner of the lobby leaves, the lobby is not destroyed. Instead, the system will automatically choose another player to become the owner of that lobby, so the multiplayer game can keep going! The lobby will not be destroyed until everyone leaves the game.
A new build is available on the beta branch. This changes the model picking system to use a different raycasting implementation under-the-hood. Sphere picking (using a radius) will also now correctly return the first hit triangle. You will also notice much faster loading times when you load up a detailed model in the editor!
Additional parameters have been added to the Joint::SetSpring command:
void Joint::SetSpring(const float spring, const float relaxation = 1.0f, const float damper = 0.1f)
The classes for P2P networking, lobbies, and voice communication have been added but are not yet documented and may still change.
This tutorial demonstrates how to create a high-quality skybox for Leadwerks Game Engine using Vue.
Cloudy Blue Skies.zip
Required Third-Party Programs
Loading the Example
Run Vue and select the File > Open menu item. Extract the zip file above and open the file "Cloudy Blue Skies.vue".
Atmosphere and Clouds
You can modify the appearance of the sky with the Atmosphere Editor. Select the Atmosphere > Atmosphere Editor menu item to open this dialog.
The clouds tab lets you adjust various properties of the cloud layers and add new ones. Skyboxes look best with multiple layers of different kinds of clouds, so don't expect to get the perfect look with just one layer.
The load button to the right side of the cloud layer list will let you select from a wide range of different cloud types.
Experiment with different cloud layers to get the look you want. The "Detail amount" setting in particular will really enhance the image, but don't overdo it. You can right-click and drag the mouse to look around in the main panel, so be sure to take a look around to see how the clouds affect the entire sky.
To edit the sunlight properties in Vue, select the sunlight object in the World Browser on the right side of the main window.
You can match the exact rotation of the default sunlight angle in Leadwerks to make your skybox line up exactly to the scene lighting. The default sunlight angle in Leadwerks is (55,-35,0). In Vue this corresponds to the values (145,0,215). To get these values we add 90 degrees to the pitch and subtract the yaw from 180. Note in Vue the order of the yaw and roll are switched.
The sun color is very important for the overall composition of our image. In real life we're used to seeing a very high range of light levels in the sky. Computer monitors cannot represent the same range of colors, so images can easily become washed out and lose details. We want to adjust the sun color so we can get the most detail within the spectrum of a 32-bit color display. Like the rotation, the sun color can be modified in the sun properties.
If the sunlight color is too bright, the image will be overexposed and the cloud shape will become washed out.
If the sunlight is too dark, it will look gray and desaturated.
The right sun brightness will give a balanced look between bright spots and shadows. This is the part in the process that requires the most artistic sense. It's a good idea to look at some screenshots or photos for comparison as you adjust your settings.
You will get quite a lot of variation in brightness across the sky, so be sure to take a look around the whole scene when you are adjusting lighting. You can also adjust the main camera's exposure value to vary the brightness of the rendered image.
If you want to hide the sun from view you can do this by setting the "Size of the sun" and "Size of the corona" settings both to zero under the "Sun" tab in the Atmosphere Editor.
To export our skybox the exporter module must be installed. Select the File > Export Sky menu item and the export dialog will appear.
The "Supporting geometry" setting should be set to "Cube". Set the X value to 1536 and the Y value to 2048. This controls the width and height of the saved image. When we press the OK button, the sky will be rendered out into a vertical cube cross with those dimensions. Each face of the cubemap will be 512x512 pixels.
By default, your skybox will be exported to the file "Documents\e-on software\Vue 2015\Objects\Atmosphere.bmp". The exported cube cross is a nonstandard orientation. To convert this into a cubemap strip ready to load in Leadwerks, use the FixVueCubemap.exe utility posted above. Drag your exported image file onto the executable, and it will save out a cube strip in PNG format that is ready to load in Leadwerks.
To import your skybox into Leadwerks, just drag the cubemap strip PNG file onto the Leadwerks main window. Open the converted texture from the Leadwerks Asset Browser. Set the texture mode to "Cubemap", uncheck the "Generate Mipmaps" checkbox, and check the clamp mode for the X, Y, and Z axes. Press the Save button to reconvert the texture and it will appear in a 3D view.
You can use the skybox in the current map by selecting it in the scene settings.
Disabling mipmap generation will reduce the size of a 1024x1024 cubemap from 32 to 24 mb. Due to the way the image is displayed, mipmaps aren't needed anyways.
For the final render, we want each cubemap face to be 1024x1024 pixels. However, we can get a better quality image if we render at a larger resolution and then downsample the image. In Vue, select the File > Export menu item again to open the export dialog. This time enter 6144 for the X value and 8192 for the Y value. Don't press the OK button until you are ready to take a long break, because the image will take a long time to render. When you're done you will have a huge image file of your skybox with a 2048x2048 area for each cubemap face.
If we resize the image file in a regular paint program, it will create seams along the edges of the cubemap faces. Instead, we're going to pass a parameter to the conversion utility to tell it to downsample the image by a factor of 50%. The "downsample.bat" file is set up to do this, so just double-click on this to launch the executable with the correct parameters. The resulting cubemap strip will be 6144x1024 pixels, with a 1024x1024 area for each face. However, due to the original rendering resolution this will appear less grainy then if we had rendered directly to this resolution.
Import this texture into Leadwerks as before and enjoy your finished high-quality skybox. Always do a low-resolution pass before rendering the final image, as it can take a long time to process.
An update is available for the new Turbo Game Engine beta.
Fixed compiling errors with latest Visual Studio version
Fixed compatibility problems with AMD hardware
Process is now DPI-aware
Added high-resolution depth buffer (additional parameter on CreateContext()).
Subscribers can download the new version here.
A small update has been published to the default branch of Leadwerks Game Engine on Steam. This updates the FBX converter so that the scene units (meters, feet, etc.) are read from the file and used to convert the model at the proper size. Previously, the raw numbers for position, scale, and vertex positions were read in as meters. The new importer also supports both smooth groups and per-vertex normals, so models can be imported more reliably without having to recalculate normals.
An error in the probe shader that only occurred when the shader was compiled for VR mode has also been fixed.
The Turbo Game Engine beta is updated! This will allow you to load your own maps in the new engine and see the speed difference the new renderer makes.
LoadScene() has replaced the LoadMap() function, but it still loads your existing map files.
To create a PBR material, insert a line into the material file that says "lightingmodel=1". Blinn-Phong is the default lighting model.
The red and green channels on texture unit 2 represent metalness and roughness.
You generally don't need to assign shaders to your materials. The engine will automatically select one based on what textures you have.
Point and spot lights work. Directional lights do not.
Setting the world skybox only affects PBR reflections and Blinn-Phong ambient lighting. No sky will be visible.
Physics, scripting, particles, and terrain do not work.
Variance shadow maps are in use. There are currently some problems with lines appearing at cubemap seams and some flickering pixels. Objects should always cast a shadow or they won't appear correctly with VSMs.
I had to include glew.c in the project because the functions weren't being detected from the static lib. I'm not sure why.
The static libraries are huge. The release build is nearly one gigabyte. But when compiled, your executable is small.
using namespace Leadwerks;
int main(int argc, const char *argv)
//Create a window
auto window = CreateWindow("MyGame", 0, 0, 1280, 720);
//Create a rendering context
auto context = CreateContext(window);
//Create the world
auto world = CreateWorld();
//This only affects reflections at this time
auto scene = LoadScene(world, "Maps/turbotest.map");
for (auto entity : scene->entities)
camera = dynamic_pointer_cast<Camera>(entity);
auto model = LoadModel(world, "Models/Damaged Helmet/DamagedHelmet.mdl");
model->Move(0, 1, 0);
//Create a camera if one was not found
if (camera == nullptr)
camera = CreateCamera(world);
camera->Move(0, 1, -3);
//Set background color
//Enable camera free look and hide mouse
//Create a light
auto light = CreateLight(world, LIGHT_POINT);
light->SetShadowMode(LIGHT_DYNAMIC | LIGHT_STATIC | LIGHT_CACHED);
light->SetPosition(0, 4, -4);
while (window->KeyHit(KEY_ESCAPE) == false and window->Closed() == false)
model->Turn(0, 0.5, 0);
if (window->KeyDown(Key::A)) camera->Move(-0.1, 0, 0);
if (window->KeyDown(Key::D)) camera->Move(0.1, 0, 0);
if (window->KeyDown(Key::W)) camera->Move(0, 0, 0.1);
if (window->KeyDown(Key::S)) camera->Move(0, 0, -0.1);
//Update the world
//Render the world
TLDR: I made a long-term bet on VR and it's paying off. I haven't been able to talk much about the details until now.
Here's what happened:
Leadwerks 3.0 was released during GDC 2013. I gave a talk on graphics optimization and also had a booth at the expo. Something else significant happened that week. After the expo closed I walked over to the Oculus booth and they let me try out the first Rift prototype.
This was a pivotal time both for us and for the entire game industry. Mobile was on the downswing but there were new technologies emerging that I wanted to take advantage of. Our Kickstarter campaign for Linux support was very successful, reaching over 200% of its goal. This coincided with a successful Greenlight campaign to bring Leadwerks Game Engine to Steam in the newly-launched software section. The following month Valve announced the development of SteamOS, a Linux-based operating system for the Steam Machine game consoles. Because of our work in Linux and our placement in Steam, I was fortunate enough to be in close contact with much of the staff at Valve Software.
The Early Days of VR
It was during one of my visits to Valve HQ that I was able to try out a prototype of the technology that would go on to become the HTC Vive. In September of 2014 I bought an Oculus Rift DK2 and first started working with VR in Leadwerks. So VR has been something I have worked on in the background for a long time, but I was looking for the right opportunity to really put it to work. In 2016 I felt it was time for a technology refresh, so I wrote a blog about the general direction I wanted to take Leadwerks in. A lot of it centered around VR and performance. I didn't really know exactly how things would work out, but I knew I wanted to do a lot of work with VR.
A month later I received a message on this forum that went something like this (as I recall):
I thought "Okay, some stupid teenager, where is my ban button?", but when I started getting emails with nasa.gov return addresses I took notice.
Now, Leadwerks Software has a long history of use in the defense and simulation industries, with orders for software from Northrop Grumman, Lockheed Martin, the British Royal Navy, and probably some others I don't know about. So NASA making an inquiry about software isn't too strange. What was strange was that they were very interested in meeting in person.
Mr. Josh Goes to Washington
I took my first trip to Goddard Space Center in January 2017 where I got a tour of the facility. I saw robots, giant satellites, rockets, and some crazy laser rooms that looked like a Half-Life level. It was my eleven year old self's dream come true. I was also shown some of the virtual reality work they are using Leadwerks Game Engine for. Basically, they were taking high-poly engineering models from CAD software and putting them into a real-time visualization in VR. There are some good reasons for this. VR gives you a stereoscopic view of objects that is far superior to a flat 2D screen. This makes a huge difference when you are viewing complex mechanical objects and planning robotic movements. You just can't see things on a flat screen the same way you can see them in VR. It's like the difference between looking at a photograph of an object versus holding it in your hands.
What is even going on here???
CAD models are procedural, meaning they have a precise mathematical formula that describes their shape. In order to render them in real-time, they have to be converted to polygonal models, but these objects can be tens of millions of polygons, with details down to threading on individual screws, and they were trying to view them in VR at 90 frames per second! Now with virtual reality, if there is a discrepancy between what your visual system and your vestibular system perceives, you will get sick to your stomach. That's why it's critical to maintain a steady 90 Hz frame rate. The engineers at NASA told me they first tried to use Unity3D but it was too slow, which is why they came to me. Leadwerks was giving them better performance, but it still was not fast enough for what they wanted to do next. I thought "these guys are crazy, it cannot be done".
Then I remembered something else people said could never be done.
So I started to think "if it were possible, how would I do it?" They had also expressed interest in an inverse kinematics simulation, so I put together this robotic arm control demo in a few days, just to show what could be easily be done with our physics system.
Turbo Game Engine is Born
With the extreme performance demands of VR and my experience writing optimized rendering systems, I saw an opportunity to focus our development on something people can't live without: speed. I started building a new renderer designed specifically around the way modern PC hardware works. At first I expected to see performance increases of 2-3x. Instead what we are seeing are 10-40x performance increases under heavy loads. Once I saw this I was very encouraged, so I decided to name the new engine "Turbo Game Engine" (the point is absolutely unmissable) and bought the domain name turboengine.com. During this time I stayed in contact with people at NASA and kept them up to date on the capabilities of the new technology.
At this point there was still nothing concrete to show for my efforts. NASA purchased some licenses for the Enterprise edition of Leadwerks Game Engine, but the demos I made were free of charge and I was paying my own travel expenses. The cost of plane tickets and hotels adds up quickly, and there was no guarantee any of this would work out. I did not want to talk about what I was doing on this site because it would be embarrassing if I made a lot of big plans and nothing came of it. But I saw a need for the technology I created and I figured something would work out, so I kept working away at it.
Call to Duty
Today I am pleased to announce I have signed a contract to put our virtual reality expertise to work for NASA. As we speak, I am preparing to travel to Washington D.C. to begin the project. In the future I plan to provide services for aerospace, defense, manufacturing, and serious games, using our new technology to deliver VR simulations with performance and realism beyond anything that has been possible until now.
My software company and relationship with my customers (you) is unaffected. Development of the new engine will continue, with a strong emphasis on hyper-realism and performance. I think this is a direction everyone here will be happy with. I am going to continue to invest in the development of groundbreaking new features that will help in the aerospace and defense industries (now you understand why I have been talking about 64-bit worlds) and I think a great many people will be happy to come along for the ride in this direction.
Leadwerks is still a game company, but our core focus is on enabling and creating hyper-realistic VR simulations. Thank you for your support and all the suggestions and ideas you have provided over the years that have helped me create great software for you. Things are about to get very interesting. I can't wait to see what you all create with the new technology we are building.
Leadwerks Game Engine 4.4 features an upgrade to the latest version of Newton Dynamics, along with a bunch of new features to enhance physics.
The new kinematic controller is a joint that lets you specify a position, rotation (Euler or quaternion), or a 4x4 matrix to orient the body to. You can set the maximum linear and angular force the joint may use to orient the entity. This allows you to create a kinematic controller that only affects position, only affects rotation, or one that controls both at once. In the video below I am using a kinematic controller to create a simple IK system with two hinge joints. The end effector is controlled by the mouse position, while the base entity stays in place, since it has zero (infinite) mass:
The kinematic controller provides much more stable collisions than the Entity PhysicsSetPosition() and PhysicsSetRotation() commands, and should be used in place of these. In fact, these commands will be removed from the documentation and should not be used anymore, although they will be left in the engine to ensure your code continues to work. The FPS player script will be updated to use a kinematic control for objects you are holding, which will eliminate the energetic collisions the script currently produces if you pick up a crate and push it into the wall.
The new joint commands are as follows:
static Joint* Kinematic(Entity* entity, const Vec3& position);
virtual void SetTargetMatrix(const Mat4& mat);
virtual void SetTargetPosition(const float x, const float y, const float z, const float blend = 0.5);
virtual void SetTargetPosition(const Vec3& pos, const float blend = 0.5);
virtual void SetTargetRotation(const float pitch, const float yaw, const float roll, const float blend = 0.5);
virtual void SetTargetRotation(const Vec3& rotation, const float blend = 0.5);
virtual void SetTargetRotation(const Quat& rotation, const float blend = 0.5);
For improved constistency in the API, the joint SetAngle function will be renamed SetTargetAngle, but a copy of the old command will remain in the engine:
virtual void SetTargetAngle(const float angle);
Hinge joints can now accept a friction value to make them more resistant to swinging around. I used this in the example below to make the joints less "loose", while a kinematic controller positions the green box:
New Vehicle Model
Newton 3.14 features a new vehicle model with a realistic simulation of a slip differential. Power is adjusted to each wheel according to the resistance on each tire.
Watch closely as the wheels below act just like a real car does when its tires slip:
The realistic vehicle models gives vehicles a much more visceral and fun feeling. The new vehicle also uses actual bodies for the tires, instead of convex raycasts, so the sudden bouncing the old vehicles could exhibit if the chassis didn't encompass the tires is eliminated.
Slider and hinge joints now have optional spring behavior you can enable with one command. Use this to make our own custom suspension system, or anything else you need.
void SetSpring(const float spring)
These changes will be available next week on the beta branch on Steam.
The beta branch has been updated. The following changes have been made:
Rolled beta branch back to release version, with changes below.
Added new FBX converter.
Fixed Visual Studio project template debug directory.
Fixed Visual Studio project template Windows Platform SDK version problem.
If everything is okay with this then it will go out on the default branch soon.
Here are the results of the Summer Games Tournament. Make sure you update your mailing address, because posters are being sent out immediately!
The arcade classic "Space Invaders" has been re-imagined with modern graphics and cute 3D aliens!
Constant is an abstract game about capturing cubes. Make sure you read the instructions!
Procedurally generated levels and a lot of interesting rooms make this FPS worth trying. Watch out for traps!
Summer is here, and you know what that means! Yes, it is time for another LEGENDARY game tournament. This year the theme is "Retro Gaming". Create a modern take on an arcade game hearkening back to the days of NES, Neo Geo, Sega, or just make anything you want. Either way, you get this totally radical poster as a prize!
How does it work? For one month, the Leadwerks community builds small playable games. Some people work alone and some team up with others. At the end of the month we release our projects to the public and play each other's games. The point is to release something short and sweet with a constrained timeline, which has resulted in many odd and wonderful mini games for the community to play.
WHEN: The tournament begins Thursday, June 21, and ends on July 31st at the stroke of midnight.
HOW TO PARTICIPATE: Publish your retro-or-other-themed game to the Games Showcase before the deadline. You can work as a team or individually. Use blogs to share your work and get feedback as you build your game.
Games must have a preview image, title, and contain some minimal amount of gameplay (there has to be some way to win the game) to be considered entries. It is expected that most entries will be simple, given the time constraints.
This is the perfect time to try making a VR game or finish that idea you've been waiting to make!
PRIZES: All participants will receive a limited-edition 11x17" poster commemorating the event. To receive your prize you need to fill in your name, mailing address, and phone number (for customs) in your account info.
At the end of the tournament we will post a roundup blog featuring your entries. Let's go!
New content has been added to Leadwerks Marketplace to provide you with assets for your games. All items are sized correctly and completely ready-to-use with Leadwerks
You can now view detailed sales records of your game assets in Leadwerks Marketplace. First, log into your Leadwerks account and navigate to the Leadwerks Marketplace main page. In the bottom-right, below the categories, a link to your paid files will appear.
Here you can see a list of all your paid items:
When you click on an item, you can see a list of people who have purchased it, along with sales dates.
If you wish to give a free license to any member for any reason, you can do so by clicking the "Generate Purchase" button. A window will pop up where you can type in the member's name and add the item to their account for free.
These tools give you more control over your game assets and better information on sales.
In evaluating possible company names I have come up with the following criteria which I used to choose a name for our new game engine.
Spelling and Pronunciation
The name should be unambiguous in spelling. This helps promote word-of-mouth promotion because when someone hears the name for the first time, they can easily find it online. Similarly, the name when read should be unambiguous in pronunciation. This helps the name travel from written to spoken word and back. Can you imagine telling someone else the name of this...establishment...and having them successfully type the name into a web browser?:
Shorter is Better
Everything else aside, fewer letters is generally better. Here is a very long company name:
And here is perhaps the shortest software company name in history. Which do you think is better?
The Name Should "Pop"
A good company or product name will use hard consonants like B, T, K, X, and avoid soft sounding letters like S and F. The way a name sounds can actually influence perception of the brand, aside from the name meaning. The name "Elysium", besides being hard to pronounce and spell, is full of soft consonants that sound weak.
"Blade Runner", on the other hand, starts with a hard B sound and it just sounds good.
The name should communicate the nature of the product or company. The name "Uber" doesn't mean anything except "better", which is why the company Uber originally launched as UberCab. Once they got to a certain size it was okay to drop the "cab" suffix, but do you remember the first time you heard of them? You probably thought "what the heck is an Uber?"
The Leadwerks Brand
So according to our criteria above, the name Leadwerks satisfies the following conditions:
The name "pops" and sounds cool.
It's not too long.
But here's where it falls short:
Ambiguity in spelling (Leadworks?)
Ambiguity in pronunciation. Leadwerks is pronounced like Led Zeppelin, but many people read it as "Leed-works".
The name doesn't mean anything, even if it sounds cool. It's just a made-up word.
These are the reasons I started thinking about naming the new engine something different.
New Engine, New Name
So with this in mind, I set out to find a new name for the new coming engine. I was stumped until I realized that there are only so many words in the English language, and any good name you come up will invariably have been used previously in some other context, hopefully in another industry or product type. Realizing this gave me more leeway, as I did not have to come up with something completely unique the world has never heard before.
Our early benchmarks indicate the new engine is a performance monster, with incredible results I did not even dream were possible. Together with the rapid development pipeline of Leadwerks, I knew I wanted to focus on speed. Finally, there was one name I kept coming back to for weeks on end. I was able to obtain a suitable domain name. I am now filing a trademark for use of this name, which requires that I begin using it commercially, which is why I am now revealing the name for the first time...
How does this name stack up?:
Unambiguous spelling and pronunciation.
The name "pops".
It communicates the defining feature of the product.
Now think about our goals for the new engine's name. Will people have any trouble remembering this name? Is there any ambiguity about what the product stands for, and the promise it makes? If two developers are at a Meetup group and one of them says "I made this with Turbo" is there any doubt what the promise of this product is, i.e. massive performance?
The name even works on a subconscious level. Anyone having trouble with their game performance (in other slow engines that aren't Turbo) will naturally wonder how fast it could be running in ours.
The fact that the name has a positive emotional response for many people and a strong connection to the game industry is a plus.
Turbo Game Engine is an unambiguous brand name that takes a stand and makes a clear promise of one thing: speed, which is incredibly important in the days of VR and 240 hz screens.
Some of you are earning money selling your game assets in Leadwerks Marketplace. This quick article will show you how to request a payout from the store for money you have earned. First, you need to be signed into your Leadwerks account.
Click the drop-down user menu in the upper right corner of the website header and click on the link that says "Account Balance".
On the next page you can see your account balance. As long as it is $20 or more you can withdraw the balance into your PayPal account by hitting the "Withdraw Funds" button.
Now just enter your PayPal email address and press the "Withdraw" button.
After that the withdrawal will be deducted from your balance and the withdrawal request will show in your account history. Shortly after that you will receive the funds in your PayPal account.
You can sell your game assets in Leadwerks Marketplace and earn a 70% commission on each transaction.
Steam Workshop was a compelling idea to allow game asset authors to sell their items for use with Leadwerks Game Engine. However, the system has turned out to have some fundamental problems, despite my best efforts to work around it.
Free items are not curated, causing the store to fill with low quality content.
Some people have reported trouble downloading items.
The publishing process is pretty tedious.
The check-out process requires adding funds to Steam Wallet, and is just not very streamlined.
At the same time, three new technologies have emerged that make it possible to deliver a better customer and seller experience through our website.
Amazon S3 offers cheap and reliable storage of massive amounts of data.
Paypal credit card tokens allow us to safely store a token on our server that can't be used anywhere else, instead of a credit card number. This eliminates the danger of a potential website hack revealing your information.
Invision Power Board has integrated both these technologies into our commerce system.
it would not have been possible to build a web store a few years ago because the cost of server space would have been prohibitive, and storing hundreds of gigs of data would have made my website backup process unsustainable. So at the time, the unlimited storage of Steam and their payment processing system was very appealing. That is no longer the case.
To solve the problems of Steam Workshop, and give you easy access to a large library of ready-to-use game assets, I am happy to introduce Leadwerks Marketplace.
The main page shows featured assets, new content, and the most popular items, with big thumbnails everywhere.
When you view an item, screenshots, videos, and detailed technical specifications are shown:
How does Leadwerks Marketplace improve things?:
Easy download of zip files that are ready to use with Leadwerks. You can use File > Import menu item to extract them to the current project, or just unzip them yourself.
All content is curated. Items are checked for compatibility and quality.
Clear technical specifications for every file, so you know exactly what you are getting.
Cheap and reliable storage forever with Amazon S3.
Any DLCs or Workshop Store items you purchased can be downloaded from Leadwerks Marketplace by linking your Steam account to your profile.
Easy publishing of your items with our web-based uploader.
We're launching with over 50 gigabytes of game assets, and more will be added continuously. To kick off the launch we're offering some items at major discounts during the Summer Game Tournament. Here are a few assets to check out:
Get "The Zone" for just $4.99:
Or download our Mercenary character for free! Just create your free Leadwerks account to gain access.
Other items will be featured on sale during the Summer Game Tournament:
After purchasing an item, you can download it immediately. All your purchased items will be shown in the Purchases area, which you can access from the user menu in the top-right of this the website header:
Here all your purchased items will be available to download, forever:
If you are interested in selling your game assets to over 20,000 developers, you can upload your items now. Sellers receive a 70% royalty for each sale, with a minimum payout of just $20. See the content guidelines for details and contact me if you need any help. If you have a lot of good content, we can even convert your assets for you and make them game-ready for Leadwerks, so there's really no risk to you.
Browse game assets now.
The latest game tournament brought in a small number of games, but they more than made up for it in quality. Each title that was submitted was pretty fantastic. The tournament was held during an odd month and there was no banner across the forum to remind people about it, so that is something that can be improved in the future. Each entry will receive an 11"x17" poster in the mail. Please make sure your name, address, and phone number (for customs) are correct and up to date in your Leadwerks account info.
Without further ado, I bring you the games:
A solid base that can be turned into a nice RPG, Dwarf Beard pits you and your beard against a horde of goblin sentries. There are several interesting mechanics and the polish is very good.
This is a fun adventure game with a and well-done visual style that looks and plays great. Find stars, collect coins, evade monsters, and reach the end goal. I was not able to progress past the first level, so I am not sure if there are more levels or not, but it's definitely worth checking out.
House in the Hollow
A shooter that is literally on rails...actual rails! Have fun blasting balloons in this spooky funhouse ride.
This is a very interesting learning game that teaches you Japanese characters. The interface still needs some work but it's a very cool idea and the polish and execution are excellent.
Also check out "VR testje weer" in the game launcher if you like killing chimpanzee zombies in VR. There's no title image so it does not qualify for the tournament...but it has monkey zombies in VR:
Internally, Leadwerks Editor uses an EventHandler class for every interface in the program. The material editor is a class extended from the EventHandler. So is the little window that has all the controls to calculate normals. So is every viewport.
The event handler class has one important function:
Every EventHandler has access to events as they occur. This is how all program actions are handled in the editor.
The plugin system will work by hooking into the event system. Each plugin will have a Lua script that receive events before the rest of the program sees them:
If the plugin makes no changes to the event then it simply returns the original event. The returned event is then sent to other event handlers.
Here is an example of a plugin that would disable the close window button on the main window. Because the function returns nil the event is discarded before the main window ever evaluates it:
if event.id == EVENT_WINDOWCLOSE and event.source == editor.mainwindow then
Here is an example of a very mean plugin that would make it so that clicking the File > Open menu item in the main window quits the program:
if event.id == EVENT_MENUEVENT then
if event.source == editor.mainwindow then
if event.extra == MENU_FILEOPEN then
event.id = EVENT_WINDOWCLOSE
Okay, now let's see if we can design a plugin for something people would actually want. Let's imagine we have a new visual material design system. The exact details of how it works are not important, it's just a system that overrides the default material editor. The design system would require materials to have a special file associated with them with the extension .DESIGN. If you open the material "brick.mat" we will look for a file in the same folder called "brick.design". If the design file is found we open the material in our special editor. If the design file is missing we will just fall back to the default material editor.
Now let's see how our system can handle this:
--Create our interface
self.window = CreateWindow("Material Designer",0,0,800,600,editor.mainwindow,WINDOW_CENTER + WINDOW_TITLEBAR + WINDOW_RESIZABLE)
if event.id == EVENT_FILEOPEN
--Check for material files being opened
--Look for design file
local designfilename = StripExt(event.extra).".design"
if FileType( designfilename ) == 1 then
--Load the design file
local stream = ReadFile(designfilename)
if stream ~= nil then
--Display our custom material editor
Print("Error: Failed to load design file.")
--Discard the event
As you can see, this approach is extremely powerful. The event IDs and design rarely change, if ever, so this allows a lot of flexibility and at the same time gives us the optimal compatibility as changes are made to the core editor. With this approach to plugins you can literally do anything you want in the editor.
I'm happy to announce the very first alpha release of Leadwerks 5 is now available.
String commands now accept a unicode overload. Add "L" in front of a string to create a wide string in C++.
Now using smart pointers. Simply set a variable to nullptr to delete an object. There is no Release() or AddRef() function.
Global states are gone. There is no "current" world or context. Instead, the object you want is passed into any function that uses it.
We are now using constant integers like WINDOW_TITLEBAR instead of static members like Window::Titlebar.
Now using global functions where appropriate (CreateWorld(), etc.).
Renderer is being designed to be asynchronous so Context::Sync() is gone. 2D drawing is not implemented at this time.
Here's the syntax for a simple program.
using namespace Leadwerks;
int main(int argc, const char *argv)
auto window = CreateWindow(L"My Game", 0, 0, 1024, 768, WINDOW_TITLEBAR);
auto context = CreateContext(window);
auto world = CreateWorld();
auto camera = CreateCamera(world);
camera->SetPosition(0, 0, -3);
auto light = CreateDirectionalLight(world);
light->Turn(45, 35, 0);
auto model = CreateBox(world);
if (window->KeyHit(KEY_ESCAPE) or window->Closed()) return 0;
if (window->KeyHit(KEY_SPACE)) model = nullptr;
You can get access to the Leadwerks 5 Alpha with a subscription of $4.99 a month. You will also be able to post in the Leadwerks 5 forum and give your feedback and ideas. At this time, only C++ is supported, and it will only build in debug mode. It is still very early in development, so this is really only intended for enthusiasts who want to play with the very bleeding edge of technology and support the development of Leadwerks 5.
Leadwerks 5 is going to be developed alongside 4.5 with an extended period of beta testing and feedback. My goal is to build the world's most advanced game design software, tailored to the needs of our community and clients. Development will first focus on a new programming API updated for C++11 and then a completely new editor using Leadwerks GUI and based on the workflow developed with our current editor.
The first beta will support the following features right away:
These features are already working. Here is a working build you can try right now:
This is the actual source code used to make this example. Note that C++11 shared pointers have been implemented for all objects and the API has been simplified to make your code more readable:
using namespace Leadwerks;
int main(int argc, const char *argv)
auto window = CreateWindow();
auto context = CreateContext(window);
auto world = CreateWorld();
auto camera = CreateCamera(world);
camera->Move(0, 0, -3);
auto light = CreateDirectionalLight(world);
light->SetRotation(35, 35, 0);
auto model = CreateBox(world);
model->SetColor(0.0, 1.0, 0.92);
while (not window->Closed())
if (window->KeyHit(EscapeKey)) break;
if (model) model->Turn(0, 1, 0);
if (window->KeyHit(SpaceKey)) model = nullptr;
The beta will be available to developers who want to try the very latest game development technology, with a subscription plan of just $4.99 a month, available through our website.