Last Good Quote: Son's are the seasoning on our lives. - Someone on Facebook

Tuesday, November 11

Thanks BDPA

I wanted to share a success story about how BDPA helped me in my career recently. Some history on me, I’ve had the pleasure of serving as the past president for the Charlotte BDPA chapter and as an educational instructor for their High School Computer Competition program. I participated in BDPA as a way to give back to my community and a way to expose young black folks to the career of IT.

I had been working a job with LogiXML, great pay but it was a 100% travel. At the time I had a 7yr and 14yr old at home and my wife was working full time. Needless to say my traveling was wrecking chaos on the family. So I decided to find a job close to home.

I happened across a job posting from a recruiting firm, Ciber. It turns out I had met someone who worked at Ciber and I recall meeting her through BDPA. So I gave her a ring. Turns out she no longer worked with Ciber but she put me in touch with the right people and gave me a good recommendation.

Three weeks later I was hired at Duke-Energy, contracting through Ciber. Great pay, great folks and good hours. I'm still here almost a year later.

I thought I’d share this with folks for two reasons. First, we network today for what we may need tomorrow. And secondly because I wanted to express my appreciate for what BDPA has done for me in my career.

Wednesday, August 27

MSSQL - When does data move from Memory to Disk

So I had to ponder this question (I had a vague idea but wanted to get a firm understanding)

Question: We know SQL stores data objects in RAM as it needs, at what point does the changes that are made in RAM get written to the disk?

In layman's terms: In the background the server monitors it's memory. When a particular object has not been used "in a while" that object is moved to disc. It is at this point that the disc and memory are syncronised. This is also done on a proper shutdown of the SQL Server.

Side Note: If memory is full of objects that are frequently used, SQL Server will read directly from disk. This can negatively impact performance in a substantial way.

From Wikipedia (link):

SQL Server buffers pages in RAM to minimize disc I/O. Any 8 KB page can be buffered in-memory, and the set of all pages currently buffered is called the buffer cache. The amount of memory available to SQL Server decides how many pages will be cached in memory. The buffer cache is managed by the Buffer Manager. Either reading from or writing to any page copies it to the buffer cache. Subsequent reads or writes are redirected to the in-memory copy, rather than the on-disc version. The page is updated on the disc by the Buffer Manager only if the in-memory cache has not been referenced for some time. While writing pages back to disc, asynchronous I/O is used whereby the I/O operation is done in a background thread so that other operations do not have to wait for the I/O operation to complete. Each page is written along with its checksumwhen it is written. When reading the page back, its checksum is computed again and matched with the stored version to ensure the page has not been damaged or tampered with in the meantime.[58]

Saturday, June 28

Review of a Stock Trader

From time to time, I find a guy giving trading advice/posts online. I like to do my own due diligence on them. Here is another one.

A review of EasyDollars, a StockTwits user.

Comparison of close the day after twit was sent (Some rounding being done)

Stock                          on 6/19/2014                  10 days after post
05/02 - SWKS                +14%                     +3%
05/12 - ORCL                 +2%                       +2%
05/14 - IWM                   +5%                       +2%
05/20 - IWM                   +7%                       +2%
05/28 - PCRX                 +10%                      +7%
05/28 - KNDI                  +8%                        -1%
05/29 - HZN                    +9%                        +1%
02/06 - FEYE                   -51%                      +9%(he did say it could go either way)
02/06 -JRJC                     -32%                       +15%
02/13 -CSIQ                   +26%                        +5.2%
12/18 -FAS                     +22%                        +10%

This guy is magic when it comes to predicting stocks. Of course I added him to my favorites.

Tuesday, June 24

Awesome Desktops

Just click the links fool...

  • The hex background
  • The white and black theme
  • Side menu is neat
  • Side Menus and all around look
  • I like the blue outline around the menu

Saturday, June 21

Bookmarked Links - Very Cool - Advertising space - Freelance talent, I like how they do things. - Design Mobile Apps (good for prototyping) - Another mobile prototyping site, check out the Kitchen Sink Demo at the bottom. - another advertisment the site, never used them though.

Friday, June 20

Quotes on Starting a Business

“Chase the vision, not the money; the money will end up following you.” -Tony Hsieh, Zappos CEO

“An entrepreneur is someone who has a vision for something and a want to create.” -David Karp, Tumblr founder and CEO
“A ‘startup’ is a company that is confused about three things: (1.) What its product is. (2.) Who its customers are. (3.) How to make money.” – Dave McClure, 500Startups co-founder

Saturday, June 14

On Creating a Startup


I recently advertised my developer's guide to launching a startup on StumbleUpon. The plus side of StumbleUpon is that all clicks are 5 cents. The downside is the bounce rate is high since people are basically channel surfing. I achieved a 96.88% bounce rate in my experiment, with an average stay of 2 seconds. I wonder if it was something I said? In my test, only 25 visitors stayed longer than 5 seconds. I paid $50 for 1000 clicks, but since only 25 of them stayed long enough to read anything, I effectively paid $2 per click. Your mileage may vary, but through this and other experiments I've gathered the following tips for advertising on StumbleUpon:
  • Your #1 goal is to get stumblers to stay longer than 5 seconds. Your #2 goal is to get them to up-vote your page. Paying $50 for 1000 clicks is one thing. Having it go viral and receiving 10,000 clicks for the same price is another.
  • Don't send StumbleUpon traffic to a landing page that asks for an email address. StumbleUpon users are notoriously fickle about providing their email.
  • People stumble to be entertained, so if your page doesn't have the potential to go viral or turn into linkbait, you will not likely fare well.
  • Blog-like content and videos seem to work best. Anything that resembles a traditional landing page will bomb.

In 24 hours, my listing was shown 26,050 times (to 3,187 unique visitors). The link in my ad was clicked 419 times, resulting in a unique click through rate of 13.15%. Not bad – that’s about $0.09 per click.

Timing of your email and Tweets
Timing is also a very important aspect for getting you covered. The best days for traffic for getting coverage of your story I have learnt are Tuesday, Wednesday and Thursday. Monday is way too fast to get you written up, the inboxes of reporters are full it's just not a great day.
At the same time, I learnt that, whilst Fridays aren't as good for traffic, the news is slower. So your chances of getting covered on that day can be higher. With a recent story about Buffer on Mashable, I took advantage of this. I followed up on a story I had pitched earlier in the week. Since it was extremely busy, I wouldn't get a response, yet a quick follow up email on Friday would receive an immediate response.

Monday, June 9

Are you secure

If you ever wondered what could be traced on your person....check out this site.

Click on the little dots in the picture to learn more.

Saturday, June 7

Random Interesting Links - 100% Free Stock Trades - no way, could this be true? - Interesting - Tech Product Reviews, make sure you buy the good stuff for the right price - See if you have been hit by the Heart Bleed Virus

Friday, June 6

Click Through Rates and Google Ad-Words
A must read on click through rates and google ad-words, this made a lot of things click for me

Saturday, May 31

Kill a Patent

If your wanting to kill some time, try this. Took me about 10 or 15 min to find a good one.

Ask Patents puts out recent software patents for the public to dispute. You think of an existing software or website that does what the patent says and submit it as prior art.

Poof - The patent is dismissed.

How to Read a Patent in 60 Seconds

Wednesday, May 28

Thanks for nothing US Airlines!

A rant....

I had a job late year where I flew every other weekend on  a consulting gig. Must have paid upward of $20,000 in airfare. As a "reward" I got 35,000 miles. Yeah for me!!! OR NOT!

I want to take a trip to Vegas, according to Orbitz I can buy a flight cash for $550. Hummm, I guess I'll use those reward miles and save some money. OR NOT!

A flight cost me 60,000 miles. I have the option to buy additional miles. Guess how much 25,000 miles guessed it....$550.

What a freakin rip-off!

Thanks for nothing US Airways!

Monday, May 26

Interesting Startups in Charlotte

I like to see IT take off in Charlotte, having said that here are some folks, in no particular order, doing it big in startups in IT in Charlotte (my home town):

Data Sharing - - Not online yet, but coming soon...maybe

Breathalyzer Phone App -

iOS Factory Floor Apps -

HR Software - - Very Cool site

Connexio Labs -

eComDash - Inventory Management and Order Fulfillment Software for Multi-Channel Ecommerce Sellers

DataLakes - Datalakes offers a comprehensive Self-Service Big Data Analytics Platform that enables enterprises to make faster accurate data driven decisions for business. (Check out the blog as well)

Dc74 - Data Center Services

BeanStalkData - CRM Applications and B2B or B2C??/ solutions

NexTable - Restaurant table reservation app(s)

2014 Startup Companies - From Venture Challenge.

I hope to add to this list in the future.


The fewer secrets I keep, the better I get at keeping them.

If somone said this to you, would you think them honest? Think on that for a while....

Saturday, May 24

Recent Bookmarks

SQL to create a line from a number of points

Friday, May 23

What is "Big Data"?

I get asked this often, usually by management level types who have heard it as a buzz word and really want to understand how it affects their business. Here's how I broke it down to my 14 year old.

If you look at the press (news, TV, commentators) big press means anything that has to do with the words, pictures and connections that people put on "social sites".

In the business world Big Data means ... well ... a lot of data. And I don't mean a little, I mean a ton. Think on the order of Billions of rows of data. A good rule of thumb would be any data that is over a Tera-byte in size. And that's the minimum.

The third thing "Big Data" could refer to is volume speed. It might not be huge in size, but how fast does the data get generated.

For example, let's say you record the date and time for any phone ring that happens within the United States in the next 30 min. And you had to pinpoint the busiest phone out of all the phones in the US. The data volume size is small. But the volume of data that comes in is crazy, your talking 2 million data points a second. And your "Big Data Solution" has to make some decision on that data within 60 seconds.

This is really the "new" and revolutionary part of Big Data as only recently (in the last 5 years) has the average computing power been strong enough to handle this volume at that speed.

The other reason "Big Data" is considered as new is because businesses have started to take new approaches to it. The goal is to figure out how all this data can be used to "hit" the bottom line.

Personal Opinion: 
The challenge that I see with Big Data is letting your solutions be driven by a measurable ROI or a measurable impact to customer.

The "Big Data" solutions that succeed are those that start with one of those two objectives in mind and move from there.

Nebulously built "repositories"/"reporting ware houses"/"business data troughs" don't really thrive in the long run. (Notice I said thrive, they serve a purpose and can be of value, but they don't generate that spark that makes the C-Level executives go nuts.)

So to put it concisely

  1. Big Data is not social data
  2. Big Data can refer to physical data size
  3. Big Data can refer to the speed of incoming data
  4. The goal is to use Big Data to affect the bottom line

Check my Facts:
IBM Article - Analytics-The real-world use of big data

Saturday, May 17

More Interesting Javascript Libraries

JQuery - Spark Lines - - free

Peity - Spark Lines - - free

SigmaJS - Draw Graphs/Node Map - - free (might be nice to draw an AI's node interface)

D3js - Just cool - - Stock Analyser Site

Jquery Dashboard Library -

Saturday, May 10

Recent Bookmarks

Stock Charting Library

A few stock charting libraries and their cost

This is in order or my preference and I typically like free *grin*

HumbleFinance - - free
    Uses Flotr and Prototype

Dcjs - - Free but uses svg not compatable with IE 8 or lower

HighCharts - - The best around but runs around $1,000

Dygraphs - - seems to be free

AnyCharts - - $399

AmCharts - - $150

Koolchart - - $600

JsCharts - - $79

ZinCharts - - $2500

Fusion Charts - - $3000 and higher

Saturday, May 3

Best Stock Charting Sites:

These sites seem to be stock charting right

Wednesday, April 30

On Leadership

If I might summarize...

True North: Stable leaders have an open mind, but they also have strong convictions and principles. While stable leaders listen to others, they are not prone to being wishy-washy. Their values drive their actions – not the court of public opinion. You might not always agree with stable leaders, but you’ll never have any doubt as to where they stand. An aligned vision based upon clearly stated values, and the character to hold people accountable to values over outcomes create a high-trust culture. Purpose and people matter more than process and short-term results.

You Play How You Practice: Whether it’s Nik Wallenda, a CEO, an educator, politician, or anyone else, your performance is always tied to your preparation. Training, development, and continuous life-long learning are the foundational cornerstones of stable leadership.

Lead With Compassion: The most stable leaders understand their success is rooted in the care and well-being of those they lead. Stable leaders have a natural bias toward empathetic and compassionate behavior. When those you lead know you care, it creates a sense of trust and stability not found in more mercenary and callous leaders.

Freedom To Fail: If the people you lead are afraid to make mistakes you’ll never see their best work – you will have led them to perpetual state of mediocrity. Smart leaders make it safe for people to think big, take risks, and try new and different things. Nothing creates stability more than a high-trust environment where people are rewarded for the right behaviors – not punished for them.

Tuesday, April 29

Let's Talk Salary

If you are in the data space, before you read the following, decide what percent of the market you fall in, in terms of performance. You in the top 10%, middle or just starting out.

OK, read on.

Management analysts use data to improve an organization’s profits and efficiency.
  • Mean: $42.30/hr or $87,980
  • Bottom 10%: $21.12/hr or $43,920
  • Top 10%: $68.16 or $141,780
  • Highest Sector: Petroleum and coal products
Financial analysts determine the best investments to sell or buy by evaluating economic data and business trends.
  • Mean: $42.18 or $87,740
  • Bottom 10%: $22.26 or $46,300
  • Top 10%: $69.99 or $145,850
  • Highest Paying Sector: Public Relations

Computer systems analysts study the needs of an organization so they can recommend hardware and software
  • Mean: $39.58 or $82,230
  • Bottom 10%: $23.74 or $49,370
  • Top 10%: $57.72 or $120,060
  • Highest Paying Sector: Animal Slaughtering (u read that right)
My Personal Take:
Bottom 10% all make nearly the same amount, but no one wants to be that guy. Financial Analysts have the potential to make the most money.

I don't know if this included bonuses but I believe that it does.

There is money to be made.

Saturday, April 26

T-SQL - What performance benefits can views give me?

I won't cover it all, but read this and stop wondering:

(Remember you gotta use them correctly, and just cause you got a hammer don't make all problems into nails)

Some highlights:

After a unique clustered index is created on the view, the view's result set is materialized immediately and persisted in physical storage in the database, saving the overhead of performing this costly operation at execution time.

these indexed views can work even when they are not directly referenced by another query as the optimizer will use them in place of a table reference when appropriate

View itself would provide us with a performance advantage (3x) over the simple use of the index alone
Using indexes to improve query performance is not a new concept; however, indexed views provide additional performance benefits that cannot be achieved using standard indexes.
This is true for MS Sql Server 2005 and beyond.

LogiAnalytics - 5 Steps to Masking Your Connection String

Hi All,

I was recently asked if there was a way to mask your connection string in Logi Studio. I thought I'd jot down some notes.

My thinking was why not put the connection string in a DLL. That will make it a bit harder for folks to find. Not exactly 128 bit encryption but each step helps. So that means I need a plugin that populates the connection string element in the Settings.xml file BEFORE the Logi report is processed.

This should be pretty straight forward.

First: There is an excellent plugin example already available on Dev-Net. But it reads from a text file which is still not masked. (Take a look)

Step 1: Fire up Visual Studio and create a new Class Library project

Step 2: Add a reference to Logi's DLL.

  • Project Properties
  • References
  • Add
  • Browse
  • In your web root folder is a "bin" folder, in there is a file called rdPlugin.dll, add that
  • Click the just added reference and in the Properties of it, set Copy Local to false. (This makes sure we don't overwrite the existing dll file when we deploy, this is imporant, do not skip)
I then used this code, it's fairly straight forward, if that doesn't makes sense to you, you probably shouldn't be going this route.

BTW: Do both of us a favor and check that your connection string is correct by putting it in a normal connection element in the Settings file.
Imports System.Xml
Imports System.Web
Imports System.IO
Public Class LogiPlugin
    Public Sub setConnectionString(ByRef rdObjects As rdPlugin.rdServerObjects)
        Dim sConnID As String = rdObjects.PluginParameters("ConnID")
        Dim xmlSettings As New XmlDocument()
        'locate your connection element from it's ID (this is passed in from the variable)
        Dim eleConn As XmlElement = xmlSettings.SelectSingleNode("//*[@ID='" & sConnID & "']")
        Dim sConnection As String = "Server=OneWickedMachine;Database=NorthWind;User Id=sa;Password=ucannothave;"
        eleConn.SetAttribute("ConnectionString", sConnection)
        rdObjects.CurrentDefinition = xmlSettings.OuterXml
    End Sub

End Class

Step 3: Deploy to the file

There are multiple ways to do this, the most stright forward...but not so formal approach

  • Build your project.
  • Browse to the Debug/Bin folder of your VS project
  • Copy the SetConnection.dll to the wwwroot/YourSite/bin folder

Step 4: Call Plugin in Studio

Open up Logi Studio and alter the Settings file

Add a Connection Element, but place "NA" in all the required attributes.

Add a Plugin element

  • Assembly Name: ..\bin\SetConnection.dll (referencial path, so you can deploy on Dev, QA and Prod
  • Class Type Name: SetConnection.LogiPlugin.LogiPlugin
  • Event: Load Definition
  • Method: setConnectionString
Add a Plugin Parameter call and ConnID = NorthWind (or your database)

Step 5: Test it!

You should be good to go from this point.

Suggestion: If you have multiple environments (Dev/QA/Prod), I would add an additional parameter for which connection string to use. This can be done within the vb file and should be pretty straight forward.

OpenID Tutorials

Facebook -

Google and Others -

Tuesday, April 22

New Website/App Checklist

My personal check list for what should happen with a new website or web app:

  1. Choose and Buy Domain
  2. Setup Host Package
  3. Put up coming soon page
  4. Setup Wordpress Blog
  5. Setup Favicon
  6. Setup 404,405 and 406 pages
  7. Setup Email
  8. Setup Google Analytics
  9. Setup Google Adwords
  10. Setup Twitter
  11. Setup Heat Click Map
  12. Setup A/B Testing
  13. Setup a Phone Line
  14. Determine Keywords
  15. Create robts.txt
  16. Setup Bank Account
  17. Setup Paypal
  18. Alpha Development Complete
  19. Create 10 Blog entries
  20. Publish Wordpress Blog
  21. Create a sitemap
  22. Blog - Press Release
  23. Blog - Screenshots
  24. Blog - How to use
  25. Blog - Who we are/what we do
  26. Alpha Testing Complete
  27. Open Alpha Testing

Additional Check Lists:

Saturday, April 19

Got Programming Skills?

Think you got programming skills?

Think you could build an app in 8 hours?

Make some money proving it....If I get enough free time, I plan to participate in one of these.

Matter of fact, if you want to do one of these I will definitely help.

Repost - Install VLC in Chrome for ChromeCast


Just like everybody else I know, I have tons of video in random formats that I can’t seem to get to play back in my web browser.  Video LAN offers an amazing video player and its installer includes a chrome extension.  This post will cover the basics for installing VLC and testing that it works as a chrome plugin:
  1. Download VLC
  2. After the download completes, click the installer.
  3. Install VLC with all of the extensions / plugins
  4. From your Chrome web browser, browse to chrome://plugins
  5. Now, you will see an option, “VLC Web Plugin”. If this line is available, you have successfully installed the VLC player plugin for Chrome.
To test the VLC plugin, you can visit the VLC Plugins demo page.

Wednesday, April 16

Agile Teams - Mange your Backlog

One of the most critical items to a team's success is managing the backlog.

The backlog is NOT a collection of to-do items that your developer can go an "pickup" when they have spare time.

A backlog HAS to be groomed. IE: Reviewed weekly by someone on the team, or maybe even the whole team.

Items at the top of the backlog list MUST have some form of requirements.

In my opinion the scrum master is responsible for keeping the backlog in order. This does not mean they are responsible for priority, requirements, etc. It means they are the one who says "Hey Team, we have to go through the backlog because we have no idea what the top 3 items actually mean"

The BA/PM/Requirement Pusher, should be intimate with the backlog. I mean REAL intimate. Live and breath it.

A bit of a rant, but it's a recurring theme that drives Agile teams to failure.

Hope it helps.

Saturday, April 12

Where did my Tax Dollars Go

Interesting data visulization:

Find more at

Saturday, April 5

More Templates I like

Admin Templates:

Thursday, April 3


I think I already wrote this post, but just in case. Here is how I implimented Autocomplete with jQuery:

You will need jquery, I had a copy in my templates, you can find a copy at

You will also need autocomplete.js, which I got from here:

I put the following with my css (in the head of the document)

.autocomplete-suggestions {
border: 1px solid #333;
font-size: 12px;
font-family: arial;
padding: 3px;

I then put the following where I wanted the text box to appear in the HTML code:

Stock: <input type="text" name="txtSymbol" id="txtSymbol">

I then put the following in my document (toward the bottom)

    var options, a;
//options = { serviceUrl:'qryStocks.php' };
var a = $('#txtSymbol').autocomplete({
zIndex: 9999,
deferRequestBy: 250, //miliseconds
noCache: false, //default is false, set to true to disable caching
onSelect: function(value, data){ alert('You selected: ' + value.value + ', ' +; }




Now we also need a file that will return the list to display in our ajax:

$time_start = microtime(true); 

$conn=new mysqli("localhost","root","ididgood","stock_tracker");

$searchString = $_GET["query"];

$sql = "select distinct symbol, symbol from stock_history where symbol like '$searchString%' order by symbol limit 10";

$result = $conn->query($sql);

$out = "{\"query\":\"$searchString\",";
$suggestions = "";
$data = "";
while ($row = $result->fetch_object()) 
if($i> 0) $suggestions.= ",";
if($i> 0) $data.= ",";
$suggestions.= "\"$row->symbol\"";
$data.= "\"$row->symbol\"";


print $out;

That's it.

Saturday, March 29

Interesting Javascript Libraries

Stumbling across some interesting stuff...

Heat Maps:

Easy Installation of Auto Complete

Gray Box/Light Box/In page popup

Auto Comment you JS code

Megamenu - Drop Downs with options

Form Menu Hints

Wednesday, March 26

Templates Links


Ones I like:

Css Buttons:

Saturday, March 22

JS Starfield

The following will create a flowing field of stars on a black background. Used the HTML5 Canvas element to create this effect:


var canvas = "";
var context = "";
var stars = new Array();

function loadStarfield()
canvas = document.getElementById("canvas_starfield");
context = canvas.getContext("2d");


//stars[stars.length-1].starSize = 50;
//stars[stars.length-1].drawColor = "#333";
//stars[stars.length-1].position.x = -10;
//stars[stars.length-1].position.y = 150;
//stars[stars.length-1].velocity.x = 1;



function starfieldLoop()
context.fillStyle = "black";
context.fillRect(0, 0, canvas.width, canvas.height);

for(var i=0;i<stars.length;i++)



function drawStar(star)
  var position = star.position;
  context.fillStyle = star.drawColor;
  context.arc(position.x, position.y, star.starSize, 0, Math.PI * 2);

function addNewStars(numStars)
for (var i = 0; i < numStars; i++)
stars.push(new Star());

function Star() {
  this.position = new Vector(randBetween(0,canvas.width),randBetween(0,canvas.height)); // Vector
  this.velocity = new Vector(randBetween(1,5),0);
  var c = randBetween(0,9);
  this.drawColor = "#FFF"; //"#" + c + "" + c + "" + c; // So we can tell them apart from Fields later
  this.starSize = randBetween(1,1);

Star.prototype.animate = function()

if(this.position.x > canvas.width)
this.position.x = 0;

// Utils
function randBetween(min, max)
return Math.floor(Math.random()*(max-min+1)+min);

function Vector(x, y) {
  this.x = x || 0;
  this.y = y || 0;

// Add a vector to another
Vector.prototype.add = function(vector) {
  this.x += vector.x;
  this.y += vector.y;

// Gets the length of the vector
Vector.prototype.getMagnitude = function () {
  return Math.sqrt(this.x * this.x + this.y * this.y);

// Gets the angle accounting for the quadrant we're in
Vector.prototype.getAngle = function () {
  return Math.atan2(this.y,this.x);

// Allows us to get a new vector from angle and magnitude
Vector.fromAngle = function (angle, magnitude) {
  return new Vector(magnitude * Math.cos(angle), magnitude * Math.sin(angle));


<canvas id="canvas_starfield" width="600" height="300"
border:5px solid black;">

Friday, March 21

Interesting Map Building Links

Ray Casting in 2D Top Down Tiles

Auto Tiling/Laying Tiles Programtically/Tile Laying algoithm

Other Links

Wednesday, March 19

Articles on World Building

World Building and World Auto Generation

Simple Rogue Like -

Random 2D Tile Map Generation

Tuesday, March 11

To My Son and My Future Self

I love you son. I want to be your friend. I want to be your confidant. I want to be your rock in stormy times. But I am your father first and foremost. That means I must prepare you for the world as best as I can. That means I must ask you to do better than me. That means I must ask of you the hard things in life. I must force you to confront your issues head on, with your head up and your eyes open. I apologize if in your youth this strains are relationship. But it is how things must be. I am your father.

You brought home poor grades, extremely poor grades. At first I was angry at you. Very Angry. I dreamed of ways to punish you and make you FEEL the retribution. How I would make you quake with the fear of god himself. Make you feel as if the very wrath of the world was upon your head. It felt good to think these things. Yes, I knew the exact methods I would take to ensure you could not contemplate a failure like this again. I had it figured out...down to the last belt stroke.

But I gave myself time. Time to simmer down. Time to realize that my anger was driven by something else. (A lesson you would be wise to learn: Anger is never the REAL reason, it is an excuse to take action). I realized that I was ashamed, embarrassed that a son of my genes, a boy with the creativity, wit and intelligence equal to my own, could not do moderately well in school. I was embarrassed because this was a public reflection of my lack of mentorship to you.  My lack of showing you how to apply discipline and persistence. My lack of teaching you what was important and what was not. It was not you who had failed, but I who had failed you. My lack of showing you how take on a challenge and succeed. This failure was on both of us. This was humbling.

I now contemplate a gentler approach, but one that will test the limits of our relationship. I will teach you how to do this thing. I will teach you how to excel at the game of life. Oh, there will be punishment but it will be with measured and calculated to demonstrate to you that there are immediate consequences for poor decision makings. Especially when one can choose a better road. Rewards will come as well, but not given cause you are "due" them, but given because you earned them by taking the harder, longer, less traveled road.

I do wonder at what point it was that this failure on my part began. I love you. I spend time with you. I take you out. I take you to hang out. I find friends for you. I taught you how to talk, walk, read, ride a bike. Never let it be said that I did not care and spend time with my son.

But I was never hard on you. Never. And shame on me for it. I claimed I wanted you to have a “nice” childhood. Not realizing that in the “roughness” of a no, there is a challenge to the little mind. A challenge to the idea that not all things come by way of words, tears, smiles and hugs. But the idea that some things only come by the hard work of your own hands. In wanting you to have an easier time of childhood, an easier one than mine, I made you unable to handle struggle.

You're 14. Maybe you are too old, I hope not. But change is in the air. I know this will start a war between the two of us. I know at your current age you will not understand. I know we may no longer be friends....for a time. This makes me terribly sad. But I know this is my responsibility. I know this right. I know this is what I need to do .... for you.

We start on this journey tonight, March 10th of 2014. I hope I have the fortitude to stay with this. I do this for myself, I do this for you and I do this for the future generations. I love you son.

Your Father,
Markus Beamer

I write this in the heat of the moment. I write it cause I have to catch this anger and bottle it up and use it to fuel me to do the right thing. I write it so one day in the far future you will know I did these things for the right reason. However it works out.

I make this public because a public declaration of intention is the strongest way to re-enforce me taking personal actions.

I also know that I am not the only one struggling with this issue, it is driven from a true love for my children. Hopefully others can learn from my mistakes.

Saturday, March 1

Spawning Monsters

I've been thinking about monster spawning. For those that might now know, this means to place a new enemy creature on a map. A few thoughts I have.

As I develop the monster spawning will get progressively complex, so this is an iterative approach.

Spawn Point - Coordinates of spawn point
Spawn Radius - As a player moves monsters will spawn within this area

  1. Check if there is more than MaxMonstersNearBy, if so exit. MaxMonstersNearBy will be set by the particular segment of the map the player is on.
  2. Check if there any players within viewing distance of the spawn point. If so exit. We don't want monsters to "pop" on the screen, players will wonder into them, or monsters will wonder into players
  3. Spawners will have a maximum number of monsters they can have spawned at any point in time.
  4. Check if there any spawn points outside of viewing distance but within SpawnRadius of the player. For each spawn point proceed.
    1. Choose a random leader, whose level is within 1 level of the player.
    2. Leaders have a number of followers that will spawn with them.
    3. Place the leader and the followers on an empty spot near the spawn point.

  1. Monsters will have one of the follow modes specified:
    1. Attack - Aggressively chase any player within x distance
    2. Guard - Stay still and attack only when attacked
    3. Wander - Moves randomly in a direction
    4. Follow - Follow a given unit, in the event that unit can not be found, start to wander.
  2. Leaders will set the mode of all followers
  3. Followers with no leader will go into wander mode.
Realistic Movement:
  1. Recall that AI processing (aiThinker) is only called once every few seconds.
  2. AI will choose 5 waypoints and move between those waypoints until the aiThinker is called again.
This is for my game Blades of War.

Thursday, February 20

Creating and Populating a Date Dimension

declare @startDateID int = 20130101
declare @endDateID int =20131231 -- 20141231
declare @truncate char(1) = 'Y'
declare @currDateID int = @startDateID
declare @currDate datetime

select @currDate = Convert(DATETIME, LEFT(@startDateID, 8))

if(@truncate = 'Y')
truncate table dim_date

while(@currDateID <= @endDateID)

select @currDate = Convert(DATETIME, LEFT(@currDateID, 8))
--print convert(varchar,@currDate)

insert into dim_date(dateID, fullDate)
values (@currDateID, @currDate)

set @currDate = DATEADD(d,1,@currDate)
set @currDateID = CONVERT(varchar,@currDate,112)


-- you may have to do something special here, or you can mark all days as tradeable
update dim_date set isTradeDay = 'Y'
where dateID in (select closeDateID
from stock_history
group by closeDateID
having COUNT(*) > 1000)

select @currDate = Convert(DATETIME, LEFT(@startDateID, 8))
set @currDateID = @startDateID

declare @priorDateID int
declare @prior5DateID int
declare @prior10DateID int
declare @prior30DateID int
declare @prior60DateID int
declare @prior90DateID int
declare @prior180DateID int
declare @futureDateID int
declare @future5DateID int
declare @future10DateID int
declare @future30DateID int
declare @future60DateID int
declare @future90DateID int
declare @future180DateID int

while(@currDateID <= @endDateID)

select @currDate = Convert(DATETIME, LEFT(@currDateID, 8))
print convert(varchar,@currDate)

select @priorDateID = MAX(dateID) from dim_date where dateID < @currDateID and isTradeDay = 'Y'
select @prior5DateID = Min(dateID) from (select top 5 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a
select @prior10DateID = Min(dateID) from (select top 10 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a
select @prior30DateID = Min(dateID) from (select top 30 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a
select @prior60DateID = Min(dateID) from (select top 60 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a
select @prior90DateID = Min(dateID) from (select top 90 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a
select @prior180DateID = Min(dateID) from (select top 180 dateID from dim_date where dateID < @currDateID and isTradeDay = 'Y' order by dateID desc) as a

select @futureDateID = MIN(dateID) from dim_date where dateID > @currDateID and isTradeDay = 'Y'
select @future5DateID = Max(dateID) from (select top 5 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a
select @future10DateID = Max(dateID) from (select top 10 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a
select @future30DateID = Max(dateID) from (select top 30 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a
select @future60DateID = Max(dateID) from (select top 60 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a
select @future90DateID = Max(dateID) from (select top 90 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a
select @future180DateID = Max(dateID) from (select top 180 dateID from dim_date where dateID > @currDateID and isTradeDay = 'Y' order by dateID ) as a

--select Max(dateID) from (select top 5 dateID from dim_date where dateID > 20130115 and isTradeDay = 'Y' order by dateID ) as a
--select Max(dateID) from (select top 10 dateID from dim_date where dateID > 20130115 and isTradeDay = 'Y' order by dateID ) as a

update dim_date
set priorDateID = @priorDateID
,prior5DateID = @prior5DateID
,prior10DateID = @prior10DateID
,prior30DateID = @prior30DateID
,prior60DateID = @prior60DateID
,prior90DateID = @prior90DateID
,prior180DateID = @prior180DateID

,futureDateID = @futureDateID
,future5DateID = @future5DateID
,future10DateID = @future10DateID
,future30DateID = @future30DateID
,future60DateID = @future60DateID
,future90DateID = @future90DateID
,future180DateID = @future180DateID

where dateID = @currDateID

set @currDate = DATEADD(d,1,@currDate)
set @currDateID = CONVERT(varchar,@currDate,112)


select * from dim_date where dateID between 20130210 and 20130230