The Ease of Not Blogging (something shiny… Value Investing)

Intelligent_Investor_25

It is easy to be excited about blogging, then over time you get busy with life and then stop doing it.  Maybe it is a bit of imposter syndrome that creeps in or being consumed by a new shiny thing that takes the attention away.  I think about writing things quite a bit and make many mental notes of what would be a good topic to blog about.  Knowing good and well at the time, that it probably will not happen unless I intentionally set aside time to write it down.

The latest thing that I have been consumed with is learning about stocks, economy, stock crashes and other light hearted fun things like that.  Ended up watching the movie The Big Short and then almost immediately watched it again to try to absorb the information from it.  I became so interested in the events of 2008 and the cause of the stock market crash and housing market collapse.  Then, when a coworker was beginning to talk about learning about investing and writing trading algorithms on Quantopian, we began to discuss it and what it would take to get started.  I have been interested in the idea of writing algorithms for trade but have been very ignorant of pretty much everything related to it.  It was an overwhelming thing to try to get started writing an algorithm with no clue on strategy or anything else and was just lost…  and really didn’t know where to start to begin to understand it.

My friend Stephen had mentioned that I should read the book Flash Boys if I was interested in writing trading algorithms.  That book was written by the same author as The Big Short, Michael Lewis.  After reading the summary of the book, went and picked it up at Barnes & Noble and could not put it down.  I tore through that book in a relatively short amount of time.  For me, that is out of the norm.  I usually read technical articles or specific things about technology but never a story about anything for fun.  Not this time, it was a story, albeit based on true events, that I was veraciously reading.  It was a fitting book to paint the hopelessness of writing a high frequency trading (HFT) algorithm.  This only made me more interested in “how” one could make long term trades to make money investing.  I was still very lost in how to get started.

I was still pretty interested in the 2008 financial collapse and the housing crisis, then read another Michael Lewis book Liar’s Poker.  This book added additional details of the mortgage backed securities that were created by Lewis Ranieri that were built upon to package and hide the sub prime mortgages in 2000’s.  This and the insurance against them is ultimately what caused the collapse in 2008.  While the housing crash was still pretty interesting, I went back to thinking about investing and algorithmic trading.

Investing and understanding how and what to invest in was still a mystery to me.  The thought of writing an algorithm without knowing the basics was almost comedic.  My time in college around economics and things like that were quickly forgotten and dismissed, mainly because I “knew” that I would never use that stuff or be interested in it.  Amazing how time always seems to change perspective and how interests swing wildly over the years.  I have alway been interested in business and business strategy for growth, etc. but never in the things of Wall Street.  Until now.

So, if you cannot beat the ETF guys because of the speed of light and the need to be in close proximity to the exchanges, all while having a huge investment in computer hardware, how do you compete?  Short answer, you don’t.  Mainly because you can’t and the better point is why would you want to?  The ETF guys make money from money by watching moves in the market to buy and sell shares to make fractions of pennies and to hold the investments for microseconds.  This is pure speculation and I think it really does more harm than good.  So, if short term speculation is the wrong way to go about investing, what is the other option?

That is when I was at Barnes & Noble again and found an interesting old book called The Intelligent Investor written by Benjamin Graham originally in 1949 and then revised multiple times.  One thing about this book is how it has stood the test of time and still seems very relevant.  The book makes the point early on for those thinking of investing by buying stocks in a company, why would you do it?  What do you know about the company financially to warrant an investment in that organization for the long haul 10 – 20 years?  Not the new tech stock IPO of Facebook or Snapchat but value investing in businesses that are growing at a steady rate.  This book teaches you to do your research, look at SEC filings and read (and understand) the financial statements for the organization that you are investing in.  This is what I had been looking for to help understand how to invest.  Even if I end up picking a few index funds to begin with, this knowledge will help understand what comprises those and to be able to see why the managers of these funds picked the companies that they invested in.

I am far from writing an algorithm at this point but I am gaining quite a bit of knowledge in the financial space.  There are quite a few additional books that I have in the queue to read, blog posts that have been following and other materials that I have been consuming to gain knowledge.  It has been a time consuming thing but this interest has been sticking with me for a while now and was a shiny distraction that caused me not to blog in a while but, it has turned into more than a brief shiny distraction.  It has opened my eyes to many things in the financial world that I have just been ignoring or have been ignorant of.  I have quite a ways to go but I am getting a great education in the various subjects and am willing to invest the time to learn it.  Wish I had paid more attention in school and maybe even pursued this as a major but, now is a good time to dive in and learn.  Who knows what I will end up doing with this knowledge but, it may serve to keep someone from taking advantage of me from my ignorance… and that is worth the time to learn more.

Advertisements
Posted in random, Value Investing | Tagged , , | Leave a comment

Event Sourcing – Part 3 – Where is my mind with the data?

As far as event sourcing goes, I wanted to pause and collect where my head is on the events that will be emitted from the instantiated models (or aggregates and entities that they are sometimes called).  I will not attempt to model a pure domain driven design and begin with my test and code first as I create this.  I have been a database guy for nearly 20 years at this point, so I do tend to take a more data first approach.

I plan on keeping the materialize view in mind to ensure I can structure the schema and data from the events that are received.  Then capture the events that make up those changes to schema and data.  We will track domain level events in the same structure and events over time but in my mind, they are more for the business level code that will be written around the events.  I will try to maintain focus on the elements that answer the questions for the materialized SQL tables.

First we need structure

In the SQL world the things that we use to define a structure are the Data Definition Language (DDL) events.  The table name, the columns, the data types, default values and possibly some of the relationships between the data.  I will not provide an opinion in the “DATA” events that will tell us anything about indexes.  Indexes are a detail that is reserved for how fast a materialization can answer a question.  We will not store the data types or length limits in “MS SQL” term but to define them a bit more universally.  No need to put an event to store the [Floor] name field data type and length as NVARCHAR(50).  We can just note in the “DML” event entry that it is a String and that the length is 50.  That way we can materialize the view in a MS SQL database, JSON object in an object database, a CSV file, whatever we want in the future.

Then we need data

Now that we know the structure that the data will be stored, we need to track the data being initialized and its changes over time.  In the SQL world the part that we use to define data changes are the data manipulation language (DML) events.  The DML is what I will be keeping in mind as I for the events to ensure that they fit with answering the questions needed when changing the values in the SQL server.  I will not be building a solution that will only work with SQL though, but my approach will be SQL first.  While that is the case, any other downstream consumers of the events should be able to materialize the data how they need to.

Storing the changes

The data changes over time will be stored in the Event Source table along with the data structure changes over time.  That way we can go back in time and see things as they were and track the necessary changes to structure, etc. over time.  From a pure Event Sourcing perspective, this may be considered a bad approach but, I am a data guy and am biased to the database questions that need to be answered.  The events for structure and the data changes will match the structure of the other domain level events that we will store and emit from our future API layer with no distinction.

I wanted to capture where my thoughts were at this point before moving on to the next step.  I am certain that my opinions will change over time and new problems will be presented in future or caused by the decisions I have made already.  Let’s track the changes in thought over time too and hopefully it will help someone along the way.  We will keep all these things in mind as we move forward to declare the model and events to get a little more structure around these thoughts.

Posted in cqrs & event sourcing, mssql | Leave a comment

Event Sourcing – Part 2 – What do we track?

We decided that we will be modeling a fictitious application called “Patient Tracks” and that we were going to use Event Sourcing backed by MS SQL.  We will take the simplest approach possible at first and then add complexity over time to the application.  The very first thing that we will start to model is the [Floor] of the building.  The [Floor] will be a container that holds other things that the [Patient] will interact with and that we will track.

Pick a place to start

Starting with the [Floor] it would be fairly easy to model this as a traditional table but our [Floor] could change over time and it would be interesting to keep all of the relevant change events that would make it up over time.  When I think of events, I think of them as two distinct types of which the first is a DATA event, where a data element is set or changed and the other event type is a MODEL event.  A MODEL event is any event that is interesting but does not explicitly set or modify the data elements of the item that we are modeling.  This may not fit the more traditional thoughts that are out there on Event Sourcing but we will move forward with this assumption.  My goal is to make it very clear and easy to model the current state of the data later on and to still have a way to emit interesting events for other things that could happen to the model but do not change it’s “DATA” state.

What is an Event?

We will define an event as anything that happened to our model in the past.  Simple enough, we have accounted for time, the noun that was acted on and we have the event that occurred to the thing.  If we can define those things, we should be able to answer quite a few questions that could be asked of the data.  We should begin to define the structure of how these items will be stored and establish the start of a contract for these data elements.

What Events could our [Floor] have?

We could think of a few events that could be emitted and stored for our [Floor] model:

  1. Floor Created (i.e. floor.created)
  2. Floor Data Modified “Name”  (i.e. floor.data.name)
  3. Floor Container Added X
  4. Floor Container Removed X
  5. Floor Deleted (i.e. floor.deleted)

Seems like a decent start for tracking what could initially happen to a [Floor] in our application.  Later, we could put “business” rules around when certain events can occur and prevent or automatically perform other events based on the rules.  We will shelve that complexity for now.  Now we need to persist this data in the database.

Storing the [Floor] in the database

Now things start to get a bit more complex as we reason about how to store the data in the database.  We want to err on the side of simplicity but the database schema should be flexible enough that we could reuse some elements.  We will model what we need for our [Floor] now and then refactor the reusable parts out to provide more flexibility.

We will put together a table to store the definition of the [Floor] model and we will use a terrible dot notation for our naming convention on the fields in the SQL tables.

CREATE TABLE [dbo].[model](
  [model.type] [nvarchar](50) NOT NULL,
  [model.event] [nvarchar](255) NOT NULL,
  [model.key] [nvarchar](50) NULL,
  [model.value.type] [nvarchar](50) NULL
)
  • model.type == is the type of object that is being modeled (i.e. Floor)
  • model.event == is the name of the event that happened to the model
  • model.key == is the key name that will be applied to the key value pair of the data.
  • model.value.type ==  is a text field that describes the type of data that will be in the value field during programatic validation.

We will keep this concept moving forward in small steps but will pick up speed soon.  The above will just serve as a model definition for the “thing” and the changes over time.  The changes will be stored in a table for each event that has occurred on each of the instantiated models.  In a future article we will define the model in the table structure and store the events that make up a [Floor].

Posted in cqrs & event sourcing, mssql | Leave a comment

Event Sourcing – Part 1 – Beginning with a clean slate

Event Sourcing has come up for a while and it is a really interesting idea but I have never implemented it from “nothing” to “something” to capture my own thoughts and reasons for doing a certain thing or not.  Event sourcing is simply where you capture all the events that make up all the things that happened to the item being tracked to deliver it to it’s now current state.  You can replay all the events, like a big journal, in order and always get the same state or end result.  Many examples out in the world show a comparison to a person’s bank account or to an accountant’s general ledger.  In these examples you do not just store a total or a customer’s account balance only, you would store all of the credits and debits that make up the current balance.  Further, if there was an error, you would never remove an entry but establish a new event that would correct the error while leaving the detail in the event history.   So our events that make up history must also be immutable and reading through them multiple times will always produce the same end result.

I have been reading about the topic of Event Sourcing and listening to different videos on the subject to gain a more general sense of the concepts to see what others are doing to solve their problems with this method.  A common name that appears in this space is Greg Young, with his talks on CQRS and Event Sourcing, he has put quite a bit of information out there on the subject.  There were many other articles and discussions with colleges about this subject as well from a conceptual standpoint.

I want to step forward a bit, out of the concepts, now that I have a very high level academic understanding and try to take my somewhat jumbled thoughts on the subject and apply them to solve a problem using Event Sourcing.  I expect that the end result of my solution will evolve quite a bit over time but I want to work through the different parts and understand why I am deciding to “do” a certain thing.  It is easy to anticipate problems and create a solution for them…  but, sometimes I end up spending quite a bit of time creating a solution for a thing that might happen during a certain edge case and not directly solving the obvious problems first.  My goal will be to build an Event Sourcing example from a clean slate and create a solution for the problems presented along the way, while sticking to the items that I feel are at the core of solving the problem.

Since I am in the Nashville area and there is quite a bit of healthcare influence here, I will deviate a bit from a traditional Event Sourcing examples and will look to create a solution for the problem domain of admissions, transfers and discharges of patients in a healthcare facility.  I would like to model a floor of a building with multiple rooms, that patients will be admitted into, then moved around over time and finally discharged.  Some patients will be readmitted and some will be new patients during the process.  Each patient will consume resources and will have services rendered that will need to be billed for.  The goal in the example is to add enough “real world” items to make it a bit more thought provoking while I work to test out the potential solution.

One of the big goals for the solution will be to answer various questions at any point in time for a patient, service provider or from the perspective of the room that was occupied.  I will forgo any notion that I am creating this solution for scale and will instead attempt to create the solution with the the most minimal items necessary.  Since I have quite a bit of experience with MS SQL, I will create the initial solution and schema with this more traditional relational store.  Then, will look to move on to a JSON document based solution to solve the problem afterward.

My next article on this subject will establish many of the necessary components that we will need and the items that we will model in the context of our simple healthcare solution that I will refer to as “Patient Tracks“.  Then we will define the boundary and scope around the models so that we can limit the problems that we are initially trying to solve.  This scope will grow outward over time but my hope is that we can establish the minimum items necessary to begin creating the early stage of our solution.  I hope that as you read, you will leave comments and ask questions so that we can establish this solution together and understand the “why” for implementing something.  Also, this exercise will be useful to me (and hopefully others) as we move through the problems and attempt to solve them with Event Sourcing.

 

 

 

Posted in cqrs & event sourcing, mssql | Tagged , , | Leave a comment

A recharging vacation and crab traps

It had been a while since me and the family had taken a truly restful vacation.  We were fortunate enough to get away long enough that I was able to unplug from the work items and to truly enjoy the downtime with the family.  We had no agenda at all each of the days we were on vacation in Pensacola, Florida.  No agenda is a wonderful thing!  Think of how almost every minute of our normal days are planned out and then you rip that away.  When to go to the beach, where to eat, what to do with yourselves… all spontaneous and based off what you WANT to do.  It took a little getting use to but we managed 🙂

We did the typical things where you go to the beach and it was a joy to watch the kids splash around.  Our oldest (N) who is 4 is fearless and charged into the waves and at times seemed like he was headed to the sandbar but forgetting that he still can’t swim; we had to keep an eye on him.  The little on (E) who is getting close to two, was a bit more timid and deliberate about his actions.  He did not like the way the ocean pulls the sand away from your feet as the water rushes back out after the waves crash in.  Lori and I just enjoyed the time and smiled at each other as we watched the kids have their new beach experiences.  We all have a distaste for the sand and can see why the beach life is a place to visit, not a place to call home for us.

One of the random days I decided to put out some crab traps that were located in the storage area of the house we were staying in.  I had never caught crab before so I knew this would be interesting.  To the Internet!  A quick search led to a few youtube videos and then 5 minutes later I was an expert.  Set out for the store and got some chicken gizzards from the local store.  Then I drove to get a gas boiler to prepare the things outside because I did not want to boil them in the house.  I mean, I had watched 5 minutes of video and was an expert…  I knew it would be easy and that buying this boiler was not a waste of time.

We got back to the house with all the materials and my 4 year old was helping me the whole time and asking questions and observing this strange behavior from his father…  normally we do technical things and this was well out of our normal day.  I did my best to explain each step and why were were doing it and he was so focused on it and helping as much as possible.  I jammed the gizzards into the two crab traps; letting them sit in the sun for just a bit to “ripen”.

With the traps set, we scoped out the best place to put the traps.  There was a canal cut behind the house and a covered boat doc was on the left corner at the back of the property.  We tested the waters with some bread to see what kind of wildlife was scurrying in the slightly murky waters and success!!  The bread we had tossed in there was instantly devoured by the tiny fish.  Now, if there were tiny fish, there were larger fish and other things that would eat them.  Our hope was the blue crab would be in there too.  I let N pick the spots to place the traps as we discussed where the crabs might be.  We lowered the traps slowly in the water and I was able to tie the tops of the ropes off on the edge of the dock so they would be really easy to retrieve.

We waited impatiently and went back into the house to kill off some time.  I has set an alarm for 15 minutes later, knowing that we would have more crab than we knew what to do with.  The time past by slowly and then finally the alarm went off!  My son jumped up and was very excited to pull in our catch.  We picked the first trap and slowly pulled up the trap by the rope and it slowly became more visible with each tug.  Then we had it to the surface and we held our breath and looked…

Nothing.

However, some of our gizzards were missing and kind of picked at.  It made sense that the fish or something had nibbled at them and pulled the bait out of the trap.  We ended up getting some stockings from the local store to solve this problem.  Now it was a little later in the day and we pushed gizzards into the stockings to form a kind of gross chicken parts tube that we then tied the top end of the stocking to the bait door of the trap.  With it being later, we just lowered the traps into the same spots to leave them there overnight.  Made sense to me and aligned with my extensive knowledge obtained from the internet videos.

Day two of the crab hunting project was under way and I had just finished my first cup of coffee when the 4 year old had gotten up too early and too excited for the time of morning.  I negotiated a second cup of coffee and a bowl of cereal before we went out to check the traps.  I was excited too but I need to have my caffeine to be a quasi functional human.  Now I had enough fuel to get going we headed out the door to check the traps.

I was not as optimistic this time.  We pulled the first trap in by the rope and as it surfaced, I did not immediately see anything.  My son shouted “we caught one!” and began to let out an excited laugh while he kind of hopped around in a celebratory manner.  Then my eyes focussed on our catch and I saw it too, we had caught a large blue crab!

Success!

We place the trap on the doc and the looked at him for a moment.  Then it hit N and he wanted to check the second trap to see if we had caught some over there.  It turns out, we had caught two more crab in the other trap!  This day was going much better.  Now what?

After catching the crab, there was the inevitable next steps that needed to be performed.  I grabbed a cooler, put some fresh water in there and some saltwater from the canal to form a slurry for the little critters.  The transfer of the crabs from the traps was interesting, because the metal tongs I was using had no grip on them and it was like watching a fencing battle as we went back and forth with our duel…  but I was inevitably triumphant.  N was so excited to see the snapping of claws and the clang of metal as the battle had raged on and now was calming down as he was looking at them in the cooler.  I pulled the smallest of the crabs up and saw that it was a female crab and we put it back in the water to go lay more crab eggs to not disrupt the ecosystem.  Amazing what you can learn in 5 minutes, huh?

I had purchased the boiler the day before but was not going to put it together until I knew we would be putting something in it.  I like to think that I have the right kind of lazy.  N and I set the traps again since it was going to take me a bit to get the boiler together, just to see if we could get a few more.  Once the boiler was together and got it all set up with the gas connected placed on the deck, I went to check the traps and we had another large male crab that we loaded into the cooler with his friends.  Now it was time to prepare things.

After a discussion with my wife, I decided to clean the crab before I boiled them and she had picked up some ice at the store that morning while she was out.  I put the ice in a bowl with clean water and carried it outside to the cooler where the crabs were waiting.  I selected the first one and dropped him into the cold water.  This caused him to go completely dormant and move extremely slow…  I welcomed this because they are quite nippy when you are trying to deal with them.  I rinsed the crab with the hose, placed one hand and thumb over the swimming claw and reached my other hand over the top of the main protective shell.  Then in a firm twisting motion, I popped the shell off of the dormant crab exposing the goopy internals as N looked closely and examined the crab with me.  The crabs have a slight fishy smell while going through this cleaning process.  I started by raking the orange organs from the center and then broke the mouth and eye section free with my hands.  Then took a small knife and cut away the lungs of the crab from each side.  I took the hose and blasted away the last bits of orange goo and other guts to clean it up.  Then immediately dropped it back into the ice water.  The clock was ticking to get them boiled.

With all three prepared and put on ice, we got the water boiling and added the necessary ingredients.  Two tablespoons of sea salt, juice of two lightly squeezed lemons and about a 1/4 teaspoon of Old Bay seasoning.  I let N drop the crabs from the ice bowl to the boiling water and he did a great job.  He grabbed them one at a time and allowed the crab to slip into the water without splashing out hot boiling water.  Pretty good job for a very hyper 4yo.  Now the crab were on the boil we had to get the butter and items in the house prepared.  We threw a plastic table cloth down, set out a plate to put the crab meat on and then put the saucer of melted salted butter on the table.  Just in time too, that had taken us close to 15 minutes to get everything situated.  That was a good amount of time for the crab to boil.

We pulled the crab from the boiling water and dropped them into some fresh ice water to cool them so we could handle them and to try a separate the meat from the shell.  We brought them in and sat a the table, began to crack them open and the dip the first piece of extracted meat into the butter.  Success!  The sweet crab meat was perfect and tasted exactly like what you would get at one of the local restaurants around us.  We enjoyed the crab and the experience was really great.  My son learned a bit about crabs sleeping forever and to appreciate where our food comes from.  It was good for me to do something non technical and I got a crab dinner out of it…  so, it was wins all around.  This was a great vacation for us and I recommend taking a vacation without an agenda and try something completely random and new.  We had a blast!

 

Posted in random | Leave a comment

Part 4 (Final) – Building a Simple JavaScript Game

To this point we have a hero and we have an enemy… now we need a fight!   We will update the world tick to include a step to evaluate the need to fight

// world tick event
function tickEvent() {
 spawnEnemy();
 fight();
}

Now we need to declare this function and put some interesting elements in here to make the hero battles interesting.  We will provide an initial roll to see who the attacker will be.  It will be more interesting if there is a 50/50 chance of the attacker being the hero or the enemy versus a very predictive back and forth battle.  So let’s code this:

// the battle function
function fight() {
   console.log(' ');
   // enemy present, fight.
   var attacker = {};
   var defender = {};

   if (roll(0,1) == 1) {
     // if roll is 1, then the attacker is the Hero
     attacker = hero;
     defender = mob[0];
   } else {
     // if roll is 0, then the attacker is the Mob
     attacker = mob[0];
     defender = hero;
   }
}

 

Now, the attacker and defender are defined in the function let’s provide a text status and get the 0 to 20 roll for the attacker and the defender:

console.log('[' + attacker.name + '] is attacking ' + defender.name + '...');

var attackerRoll = roll(0,20);
 var defenderRoll = roll(0,20);

console.log ('[' + attacker.name + '] the attacker rolled: ' + attackerRoll);
 console.log ('[' + defender.name + '] the defender rolled: ' + defenderRoll);

 

We know the attackers roll and if it is Zero, they have missed their attack.  We can provide that basic If logic to contain the rest of the damage calculations.

if (attackerRoll == 0) {
   // miss
   console.log('[' + attacker.name + '] missed the Attack!!')
} else {
   
}

 

We can check the rolls now and if the defender roll is higher than the attacker, then the defender was able to block the attack.  This should work out but may produce some long battles.  We will see what happens.

 if (attackerRoll == 0) {
     // miss
     console.log('[' + attacker.name + '] missed the Attack!!')
 } else {
   if (defenderRoll > attackerRoll) {
     console.log('[' + defender.name + '] blocked the Attack!');
   } else {
      // hit for the attacker

   }
}

 

At this point we can see if the attacker has hit the opponent.  Let’s do a simple calculation to create and capture the damage.  We will do this in the  section labelled // hit for the attacker.   If the attacker and defender roll are equal we will add one to the number to ensure there is a small hit to move the fight forward.

var damage = attackerRoll - defenderRoll;
damage ++ // award one point hit if a draw.
console.log('[' + attacker.name + '] hit ' + defender.name + ' for +' + damage + ' damage!');

// issue the damage
if(attacker.name != hero.name) {
   hero.health -= damage;
} else {
   mob[0].health -= damage;
   if(mob[0].health > 0) {
     console.log('[' + mob[0].name + '] health is at ' + mob[0].health + ' of ' + mob[0].maxHealth);
   }
}

 

That should be sufficient for a simple fight that has enough randomness to be interesting.  The outcome of each battle should be fairly random.  This will track the attacks and various damage for the enemy and the hero but there is no check to see if one of them died in the battle.  Presently, this script would tick on for infinity and go deep into the world of negative health.  Let’s correct that with a new function that will be evaluated every world tick to check for death.

// world tick event
function tickEvent() {
 spawnEnemy();
 fight();
 deathCheck();
}
function deathCheck() {
 if(hero.health <= 0) {
   console.log('[' + hero.name + '] our hero has fallen in battle. Game over.');
 }

 if(hero.health > 0 && mob[0].health <= 0) {
  console.log(' ');
  console.log('[' + hero.name + '] has slain the ' + mob[0].name + '!!!');
  console.log(' ');
  console.log("*********************************************************");
  mob.splice(0, 1);
 }
}

That is pretty straight forward, if the hero health is less than or equal to zero then post a game over and if the enemy has the same, we will post a death and remove the enemy from the array with the splice command.  One house keeping item in the logic flow is if the hero has died, we should stop the world tick even.  We can do the same hero health check there or do a game over variable.  For now, I will just check the health:

function worldClock() {
  if (hero.health > 0) {
   tickEvent();
  }
 
  setTimeout(worldClock, world.clockInterval); 
}

 

We should track our hero’s kill count as he moves forward in battle.  Let’s add a place to store the value with the hero:

// our hero
var hero = {
 name: "Foff",
 health: 100,
 crit: 5,
 strength: 10,
 block: 50,
 kills: 0
};

Now we will just increment the kills in the deathCheck function

hero.kills ++;

And we will post the kills along the way so we can track the hero status.  While we are changing the deathCheck function we will put in a reward for a kill to prolong the life of our warrior as he progresses through the game.  For this initial reward, we will give the hero a +25 to his health to make things interesting.  Here is the revised function:

function deathCheck() {
 if(hero.health <= 0) {
 console.log('[' + hero.name + '] our hero has fallen in battle. Game over.');
 console.log('[' + hero.name + '] killed %s before death.', hero.kills);
 }

if(hero.health > 0 && mob[0].health <= 0) {
 console.log(' ');
 console.log('[' + hero.name + '] has slain the ' + mob[0].name + '!!!');
 console.log(' ');
 console.log("*********************************************************");

  console.log('[' + hero.name + '] has gained +25 health for the kill!');
  hero.kills ++;
  console.log('[' + hero.name + '] kills ' + hero.kills);
  hero.health += 25;
  mob.splice(0, 1);
 }
}

 

One thing of interest now that we have covered the death check would be how the hero health is doing after each attack.  A new function will be added to the world tick event and called to post this output.

// world tick event
function tickEvent() {
 spawnEnemy();
 fight();
 deathCheck();
 postHeroHealth();
} 

function postHeroHealth() {
  if (hero.health > 0) {
    console.log('[' + hero.name + '] health is at ' + hero.health);
  }
}

 

Here is our final code that pulls together all of the early battle logic:

var world = {
 clockInterval: 0,
};

// our hero
var hero = {
 name: "Foff",
 health: 100,
 crit: 5,
 strength: 10,
 block: 50,
 kills: 0
};

var orc = {
 name: "Orc", 
 health: 23,
 maxHealth: 23,
 crit: 1,
 strength: 5,
 block: 10
};

// the current mob we are battling
var mob = [];

function worldClock() {
 if (hero.health > 0) {
 tickEvent();
 }
 
 setTimeout(worldClock, world.clockInterval); 
} 

// world tick event
function tickEvent() {
 spawnEnemy();
 fight();
 deathCheck();
 postHeroHealth();
} 

// random roll function for the chance of the game
function roll(min, max){ 
 return Math.floor(Math.random() * (max - min + 1) + min); 
}

// spawn an enemy
function spawnEnemy() {
 if(mob.length == 0) {
 // no enemy, spawn one
 mob.push(new Object(orc));
 mob[0].health = mob[0].maxHealth;

 console.log("*********************************************************");
 console.log(' ');
 console.log("A new enemy " + mob[0].name + " has been spawned...");
 } 
}

// the battle function
function fight() {
 if(mob.length > 0) {
 console.log(' ');
 // enemy present, fight.
 var attacker = {};
 var defender = {};

 if (roll(0,1) == 1) {
 // if roll is 1, then the attacker is the Hero
 attacker = hero;
 defender = mob[0];
 } else {
 // if roll is 0, then the attacker is the Mob
 attacker = mob[0];
 defender = hero;
 }

 console.log('[' + attacker.name + '] is attacking ' + defender.name + '...'); 

 var attackerRoll = roll(0,20);
 var defenderRoll = roll(0,20);

 console.log ('[' + attacker.name + '] the attacker rolled: ' + attackerRoll);
 console.log ('[' + defender.name + '] the defender rolled: ' + defenderRoll);

 if (attackerRoll == 0) {
   // miss
   console.log('[' + attacker.name + '] missed the Attack!!')
 } else {
   if (defenderRoll > attackerRoll) {
     console.log('[' + defender.name + '] blocked the Attack!');
   } else {
     // hit for the attacker
     var damage = attackerRoll - defenderRoll;
     damage ++ // award one point hit if a draw.
     console.log('[' + attacker.name + '] hit ' + defender.name + ' for +' + damage + ' damage!');

     // issue the damage
     if(attacker.name != hero.name) {
       hero.health -= damage;
     } else {
       mob[0].health -= damage;
       if(mob[0].health > 0) {
         console.log('[' + mob[0].name + '] health is at ' + mob[0].health + ' of ' + mob[0].maxHealth);
       }
     }
   }
 }
 }
}

function postHeroHealth() {
 if (hero.health > 0) {
 console.log('[' + hero.name + '] health is at ' + hero.health);
 }
}

function deathCheck() {
 if(hero.health <= 0) {
 console.log('[' + hero.name + '] our hero has fallen in battle. Game over.');
 console.log('[' + hero.name + '] killed %s before death.', hero.kills);
 }

 if(hero.health > 0 && mob[0].health <= 0) {
 console.log(' ');
 console.log('[' + hero.name + '] has slain the ' + mob[0].name + '!!!');
 console.log(' ');
 console.log("*********************************************************");

 console.log('[' + hero.name + '] has gained +25 health for the kill!');
 hero.kills ++;
 console.log('[' + hero.name + '] kills ' + hero.kills);
 hero.health += 25;

 mob.splice(0, 1);
 }
}



// start the world clock ticking along
worldClock();

 

 

That is it!  Now we can have an early battle.  Let’s call node and run our script to see how our hero does in battle.  Here is an abbreviated output of the end of our battle:

...

[Foff] is attacking Orc...
[Foff] the attacker rolled: 0
[Orc] the defender rolled: 15
[Foff] missed the Attack!!
[Foff] health is at 2

[Foff] is attacking Orc...
[Foff] the attacker rolled: 18
[Orc] the defender rolled: 10
[Foff] hit Orc for +9 damage!

[Orc] health is at 3 of 23
[Foff] health is at 2
[Foff] is attacking Orc...
[Foff] the attacker rolled: 5
[Orc] the defender rolled: 13
[Orc] blocked the Attack!

[Foff] health is at 2
[Orc] is attacking Foff...
[Orc] the attacker rolled: 20
[Foff] the defender rolled: 10
[Orc] hit Foff for +11 damage!

[Foff] our hero has fallen in battle.  Game over.
[Foff] killed 92 before death.

 

Not bad!  He slaughtered 92 before his demise!  I may shelve this project for a bit and move on to something else but we have a very simple game that we could continue to expand and adapt to make it even more interesting in the future.  I hope you have liked tracking the progress of this and please send over your recommendations for next steps and modifications that could be made!

Thanks!

 

Posted in coding, node js, random | Tagged , | Leave a comment

Part 3 – Build a Simple JavaScript Game

As we continue the progress of this simple JavaScript game we need to add an enemy for our hero to battle.  The first type of enemy that we will construct will be an Orc and will be easy to model based on the elements that we established with our hero.  There is an early design element that we will consider that will add a bit of complexity initially.

In the previous article we tried to maintain focus on the minimum required elements  to make the game functional, without adding unnecessary complexity.  As a first element for our enemy, we will include an array to hold a group of enemies.  That will allow our hero to battle a group at a time versus just one.  It is a simple enough item to include initially and avoid some refactoring in the future.

// the current mob we are battling
var mob = [];

The mob array will give us a place to hold our enemy.  Now we need to construct our Orc object so that we can instantiate it for battle.  Based on what we selected for our hero, we can just replicate the same items for the creature that we will battle.

var orc = {
	name: "Orc",	
        health: 20,
        crit: 1,
        strength: 5,
        block: 10
};

We will make our early enemy clearly subordinate in health and other stats as compared to our hero.  Since the hero will battle many enemies over time, it will be necessary to have the enemies be weaker than our primary toon.

Let’s create a quick function to spawn an enemy that we can evaluate as the world ticks forward in time.  It will need to evaluate the presence of an enemy in the array and then it will instantiate an enemy for us.

function spawnEnemy() {
        if(mob.length == 0) {
           // no enemy, spawn one
           mob.push(new Object(orc));
        }
}

This is a very basic function that will evaluate if there is an enemy or not and if not, it will push a new Orc into the array.  Since the function will create no more than one enemy initially, we will add it to the world tick event to be evaluated continually to ensure our hero always has a foe to battle.  While we are in here, we will clean up the roll function and early items created as the game begins to take shape.  We will strike the min and max items from the world object and will modify our Roll function to take a min and max parameter directly.

function roll(min, max){
   return Math.floor(Math.random() * (max - min + 1) + min); 
}

Now we can put the script all together and include the most recent changes.

var world = {
   clockInterval: 1500,
};

// our hero
var hero = {
	name: "Foff",
	health: 100,
        crit: 5,
        strength: 10,
        block: 50
};

var orc = {
	name: "Orc",	
        health: 20,
        crit: 1,
        strength: 5,
        block: 10
};

// the current mob we are battling
var mob = [];

function worldClock() {
    tickEvent();
    setTimeout(worldClock, world.clockInterval); 
} 

// world tick event
function tickEvent() {
    spawnEnemy();
} 

// random roll function for the chance of the game
function roll(min, max){ 
    return Math.floor(Math.random() * (max - min + 1) + min); 
}

// spawn an enemy
function spawnEnemy() {
   if(mob.length == 0) {
     // no enemy, spawn one
     mob.push(new Object(orc));
     console.log("A new enemy " + mob[0].name + " has been spawned...");
    } 
}

// start the world clock ticking along
worldClock();

 

That will finish things up for today and we will create a function for a battle next time.

Posted in coding, node js | Tagged | Leave a comment