Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

1. May 2011

 

Hmmmm, really need to settle on a name for the bipedal robotic characters that isn't Mech/Mecha soon just to ease these conversations! Not my most creative day so I’ll just go with GPR now.

 

Anyways, the GPR is very much fundamental to the game.  One of my favorite things about Autoduel and Mechwarrior Mercs was the sense of acquisition.  Start with a lowly machine and work your way up the ranks.  One of my favorite factors of Chromehounds was the customization aspect.  I intend to incorporate both into our game.

 

The very first Mech, er GPR the character starts with is power_loadervery primitive, like the Powerloader from Aliens that Ripley used.  Very simple bipedal machine with a single weapon forward firing weapon mount.  As the player wins matches, they will have the option of swapping that weapon out for better weapons and eventually with be able to buy better GPR frames.  In the end though, it will entirely be about trade offs.

 

Each frame will have a certain number of slots available, of different sizes to accommodate different sized weapons.  Additionally frames will be able to have different power plants, that will be a factor in speed, battery life, weapon power and charges.  So you could mount a big heavy laser, that really sucks the juice or mount smaller engine which would be lighter and faster but couldn’t power the weapons as well.

 

It is all about trade offs, so you could create a fast lightly armed frame, or a heavily armed slow machine or simply an average all around machine.  You could also use munitions based weapons like rocket launchers or machine guns that don’t use energy from the engine, but once they run out of ammunition are as good as useless. 

 

cci_40All frames start with a certain amount of energy, tied to the type of power plant installed.  Things like the weight of the frame ( from weapons and armor ), firing of energy weapons, running at high speeds, taking damage from certain types of weapons, etc.  If energy goes to zero, you stop dead and can’t fire.  Engines will recharge slowly on their own, so you need to balance speed and weapon use to keep your power levels healthy.  Or, go with a power plant that has a rapid recharge rating.  In my head now, statistically a power plant is rated by:  size ( amount of space needed by frame to install ), weight, power available, recharge rate and frame class(es) ( what size of frames the engine can be install into ) and finally cost.

 

Frames work on a very similar manner, with various weight classes, like featherweight, light, medium, etc…  In addition they have variant number of weapon mounts of different types ( forward facing, 360, back facing, 360 degrees auto tracking, pod based, etc ), maximum weight for all add-ons ( engines, weapons, armour, etc ), maximum internal space for engines.

 

So, in the beginning, machines would be only a few meters tall, with a single weapon and underpowered engines and minimal armor.  By the end though, the player could be piloting a literal titan, several meters tall and bristling with weapons and armor.  Of course then, so will their enemies. 

 

From a developers perspective, this means I need to figure out how to make weapons44784_md-Guard, Imperial, Sentinel, Tank, Walker, Warhammer 40,000 modular.  In the end I imagine this comes down to dynamic parenting of bones, but it is something I need to look into from a technical point of view before continuing too far ahead.  I had been tempted to make frames even more customizable, so different legs, torsos, cockpits, arms and weapons, but truth is I think the level of work is too high to handle right now, especially when it comes to creating the animations.  If the modular weapons end up being not too difficult, I may revisit this concept.

 

You know, the name Frames is starting to grow on me.  BattleFrames?  Battle Frame Formats?  Yeah, that’s the perfect name, BFF!  Oh, wait….  *groan*  Back to the drawing board.

 

For those looking at the various inspirational images in this post, they are from the top Ripley in a Power Loader in Aliens, the Walker from Avatar and finally the Imperial Guard Walker, which is probably the closest in my minds eye to the kind of vehicle the player will start in.  Think of it like the go-cart of Frames.

Design

30. April 2011

While working on an upcoming beginners guide to Wings, I put some thought into something I had never really thought about before…  what the heck was the “Crease” command for?  Functionally it seemed identical to extruding an edge along its normal.  After some messing around though, I figured out the very small but somewhat important difference between the two commands.

The following video shows the difference in action.

Extrude vs Crease in Wings 3D

 

As you see, with Extruding, a 5 sided polygon is created just past the edge that was extruded.  With crease the polygons are created using the next available vertex along the edge.  This is a very minor distinction, as otherwise the two functions are almost identical, but the effect is most pronounced once smoothing is applied.

CreaseVsExtrudeResults

 

So, damned near the same, but slightly different.  But in answer the question “Whats the difference between extruding and crease?” the answer is “not much”.

Art

30. April 2011

6a00d8341c858253ef00e54f2306618834-640wiSo, choosing Blender for my art pipeline has some very big upsides, and a couple massive downsides.

 

Amongst the biggest downsides is that Blender is in the midst of a very long move from 2.4x to 2.5x, which means you are effectively using beta software in production.  Frankly, the 2.5x branch is probably as stable as the 2.4x branch with some major feature improvements.  That said, there is a giant downside… all kinds of documentation is simply and massively WRONG.

I just spent 2 hours trying to get a textured model into Unity, and for the love of all that is, I simply couldn’t get textures to work.  After many google sessions, I read that TexFace needs to be enabled… simply press F5 or F9, but again, these instructions are for 2.4x and are outdated.

I finally found the way after much confusing.

Properties->Material Icon ( the Ball )->New Material->Assign, then scroll down to Options and click Face Textures.  Done.  That was intuitive now, wasn’t it?

 

The following video illustrates that process.  Again of key note If you are using Blender with Unity, your textures WILL NOT WORK if you do not follow this process.

 

Enabling TexFace in Blender 2.56

Art , ,

29. April 2011

I just received the following email and thought I would pass it on.  I’ve received a few of these offers, so if you are looking to purchase in the future, wait for the next promo.

 

Greetings,

At Unity, we love games and want to see your game on mobile devices. To help get your Unity-powered game live in the App Store or available on any of the 30 million-plus Android devices out there, we are offering you a 20% discount on your purchase of a Unity iOS or Unity Android license. Simply visit our online store by April 30th and enter UFRM0430 when asked for your Rebate Code.

Unity Mobile - 20% off

Enjoy,
The Unity Team

Both links edited as they contained tracking info linked to my email address.

General

26. April 2011

So today, after 6 days of downtime I get word from Sony that apparently mine and 75 million other accounts have been compromised, including pretty much all of my personal information. Worst of all, this information included my password and possibly my credit card information.

 

This is an unforgiveable sin on many levels, but more than anything I have to say this… if you are storing sensitive information in your game, encrypt the hell out of it!  Really, it’s not that hard.  Actually here is how you do it…  this is code I have used in another project, but sadly I forget exactly where I got it from for proper crediting.  So, if you are the author, let me know and I will give proper accreditation.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ConfigurationLibrary
{
    public sealed class CryptoString
    {
        private CryptoString() { }
        private static byte[] savedKey = ASCIIEncoding.UTF8.GetBytes("YOURVALHERE");
        private static byte[] savedIV = ASCIIEncoding.UTF8.GetBytes("YOURVALHEREASWELL");
        public static byte[] Key
        {
            get { return savedKey; }
            set { savedKey = value; }
        }
        public static byte[] IV
        {
            get { return savedIV; }
            set { savedIV = value; }
        }
        private static void RdGenerateSecretKey(RijndaelManaged rdProvider)
        {
            if(savedKey == null)
            {
                rdProvider.KeySize = 256;
                rdProvider.GenerateKey();
                savedKey = rdProvider.Key;
            }
        }
        private static void RdGenerateSecretInitVector(RijndaelManaged rdProvider)
        {
            if(savedIV == null)
            {
                rdProvider.GenerateIV();
                savedIV = rdProvider.IV;
            }
        }
        public static string Encrypt(string originalStr)
        {
            // Encode data string to be stored in memory.
            byte[] originalStrAsBytes = Encoding.ASCII.GetBytes(originalStr);
            byte[] originalBytes = { };
            // Create MemoryStream to contain output.
            using(MemoryStream memStream = new
                     MemoryStream(originalStrAsBytes.Length))
            {
                using(RijndaelManaged rijndael = new RijndaelManaged())
                {
                    // Generate and save secret key and init vector.
                    RdGenerateSecretKey(rijndael);
                    RdGenerateSecretInitVector(rijndael);
                    if(savedKey == null || savedIV == null)
                    {
                        throw (new NullReferenceException(
                                "savedKey and savedIV must be non-null."));
                    }
                    // Create encryptor and stream objects.
                    using(ICryptoTransform rdTransform =
                           rijndael.CreateEncryptor((byte[])savedKey.
                           Clone(), (byte[])savedIV.Clone()))
                    {
                        using(CryptoStream cryptoStream = new CryptoStream(memStream,
                              rdTransform, CryptoStreamMode.Write))
                        {
                            // Write encrypted data to the MemoryStream.
                            cryptoStream.Write(originalStrAsBytes, 0,
                                       originalStrAsBytes.Length);
                            cryptoStream.FlushFinalBlock();
                            originalBytes = memStream.ToArray();
                        }
                    }
                }
            }
            // Convert encrypted string.
            string encryptedStr = Convert.ToBase64String(originalBytes);
            return (encryptedStr);
        }
        public static string Decrypt(string encryptedStr)
        {
            // Unconvert encrypted string.
            byte[] encryptedStrAsBytes = Convert.FromBase64String(encryptedStr);
            byte[] initialText = new Byte[encryptedStrAsBytes.Length];
            using(RijndaelManaged rijndael = new RijndaelManaged())
            {
                using(MemoryStream memStream = new MemoryStream(encryptedStrAsBytes))
                {
                    if(savedKey == null || savedIV == null)
                    {
                        throw (new NullReferenceException(
                                "savedKey and savedIV must be non-null."));
                    }
                    // Create decryptor and stream objects.
                    using(ICryptoTransform rdTransform =
                         rijndael.CreateDecryptor((byte[])savedKey.
                         Clone(), (byte[])savedIV.Clone()))
                    {
                        using(CryptoStream cryptoStream = new CryptoStream(memStream,
                         rdTransform, CryptoStreamMode.Read))
                        {
                            // Read in decrypted string as a byte[].
                            cryptoStream.Read(initialText, 0, initialText.Length);
                        }
                    }
                }
            }
            // Convert byte[] to string.
            string decryptedStr = Encoding.ASCII.GetString(initialText);
            return (decryptedStr);
        }
    }
}

Now its as simple as calling ConfigurationLibrary.CryptoString.Encrypt(somestring);  and ConfigurationLibrary.CryptoString.Decrypt(somestring).

 

It is this easy to encrypt your info, compromising your users security is never justified!  Just be sure to protect your encryption keys as much as possible.

 

For the record, I don’t know if Sony encrypted this information or not, but they haven’t communicated that they did, which leads me to believe that they didn’t.  If they did, Sony has done a horrible job at PR.  If they didn’t, Sony made a mistake a first year CS student never should have!  Either way, Sony just screwed up really badly.

Programming, Totally Off Topic , ,

Month List

Popular Comments