Population Metrics Build Jam Entry

local HowToGuide = {}

	-- 'What Is This Tool Used For?' --
	
	-- This Tool Gives You The Basic Building Blocks For Making A City With Population Metrics
	-- And Example AI Scripts, But Can Also Be Easily Modified And Applied In Other Genres
	
	-- This Tool Is Used For Gathering Population Metrics, These Are Currently Each
	-- AI's Feeling Of Happiness, Safety, Social and Health. This Could Be Used In 
	-- A Wide Array Of Games Such As Games Involving A Population. Maybe Even Multiple Populations
	-- By Duplicating The 'AI' Script And Renaming The Script In It 
	-- To Something Else And Then Referencing That Script In 'PopulationMetrics', The Same
	-- Way As The Example Provided In 'PopulationMetrics'
	-- This Could Also Maybe Be Modified For A Survival Game. You Can Change 
	-- And Add New Feelings And Behaviours To The AI Such As To Make Them Hostile 
	-- Or Friendly (See The 'GoToPlayer' Script For More Details On That) 
	-- Or Even Add Feelings To The Player Which Could Be Used
	-- To Indicate A Thirst Value For A Survival Game And Use The Helper Functions
	-- To Set Or Increment That Value Which Can Be Easily Set Up Using The Format 
	-- Provided In The 'AI' Script. I've Made It Easy To Access Each AI's Stats
	-- Individually, Go To The Bottom Of The PopulationMetrics:CalculateValues() 
	-- Function To See How. But Firstly, Continue To Read This Document 
	-- Throughout Before Making Any Changes Or Alterations So You Know How To Best 
	-- Use And Adapt This Tool.
	
	-- It Is Relatively Straight Forward To Add New Feelings, If You Want To Know
	-- How This Works Keep Reading, Which Is What I'd Advise You Do Before Making 
	-- Any Changes. 
	
	-- To Add New Feelings Scroll Down To The 'How Can I Add My Own 'AI' Feelings?'
	-- Header. If You Want To Add The Player's Feelings Into The Average And/Or
	-- Add Player's Feelings, See The 'How Can I Add Feelings To The Player' Header.
	
	-- There Is Also Example AI Scripts For If You Don't Understand AI Yet
	-- See 'And Then We Have The Helper Scripts' Header For More Details.
	
	-- These Scripts Can Be Added To Relatively Easily With Each Script Explaining
	-- How They Can Be Extended And Changed To Fit A Wide Variety Of Purposes.
	
	-- My Goal With This Is Also For This Tool To Be Firstly Adapted And Edited To Whatever
	-- You Wish To Adapt Too, And Secondly, For People To Learn From This Tool Which Is Why
	-- I Left Areas Of This Tool In Which It Could Be Made More Efficient Deliberatly
	-- For People To Learn From And Highlighted These Areas In The Scripts. Now, There's
	-- Probably Other Areas Of This Tool Where I Haven't Noticed Where It Could Be Made
	-- More Efficient And I Encourage You To Find These Areas To Improve This Tool For However
	-- You Wish To Use It.
	
	-- 'So, How Does This All Work?' --
	
	
	-- We'll Take It From The Top Of The 'PopulationMetrics' Downwards --
	
	
	-- We First Initialise A Bunch Of Variables In The 'PopulationMetrics.Properties' --
	
	
	-- 'AllAI' Is Of A Type 'scriptasset' And What This Means Is That It Is A Reference Used
	-- To 'Talk To' Other Scripts And Send And Retreive Data From And To The Scripts
	
	-- 'AllAISize' Is Of Type 'number' Which Is, Well You Probably Guessed It's A Number :O
	-- This Is Used A Bit Further Down In The PopulationMetrics:AmountOfAI() To Find Out How
	-- Many AI's Are In The Game, We Use This So We Know How Many Are Actually There
	
	-- Then We Get Onto The 'Averages' These Are AverageHappiness, AverageHealth, 
	-- AverageSocial and AverageSafety, You Can Add More (See Question Below) But 
	-- I'd Finish Reading This First So You Know How This System Works First Before 
	-- Changing It. These Averages Are Used To Show On Screen The Average Amount For
	-- Each Current Feeling In The Game. You Can Remove/Change The UI Widget If You Wish
	-- It's Currently There For Demonstration Purposes Which Is Why It's So Big. These Averages
	-- Are Calculated In PopulationMetrics:CalculateValues() 
	
	-- Then The Last Property Is The UIManager, This Is Of Type Entity Which Is
	-- Everything In The Entity Window, But Hang On, You Can't See The Entity?
	-- Reason For That Is Because It's On The Player, Click On The World DropDown
	-- Then Navigate To 'Player', It's Located On There. Then If You Scroll Down
	-- The 'UIManager' Is There. The Way We Can Access This Is Through The 
	-- PopulationMetrics:OnCollision(interactingEntity) Function Which Occurs
	-- When You First Load Into The Game As The Player Immediatly Stands On It.
	-- You Can Change This However You May Like But For Now, This Is The Way I Chose
	-- To Access This, You May Wish To Use A 'Trigger' Which Is Invisible And This Is What I Would
	-- Advise If You Use This System For It To Be More Discreet, I Did It This Way
	-- For Demonstration Purposes
	
	
	-- Now We Move Onto The Init Function --
	
	
	-- Firstly We Use 'AllAI' To Get, Well, All The Entities With The AI Script (I'll Move Onto 
	-- Explaining That Script Later).
	
	-- Then We Call The AmountOfAI() Function In This Script (Why The 'self:' Is There Before It)
	-- To Calculate The Amount Of Entities With The Script 'AI' Attached To It
	
	-- Then We Do A Timed Function Which Is Called A Schedule, What This Does Is I've Set It Up
	-- To Wait For One Second And Then Call The CalculateValues() Function Which Is In This Script
	-- I've Done This To Avoid A Bunch Of Errors Appearing In The Console Saying The UIManager Value
	-- Is Nil (AKA Has No Value) Because We Got To Get That From The
	-- PopulationMetrics:OnCollision(interactingEntity) Remember? Then When That Schedule (Timed Function)
	-- Is Done, We End It and Then End The Init Function
	
	-- I've Left An Empty function PopulationMetrics:OnTick() Just In Case You Want To Use It For
	-- Something Potentially, What That Does Is It Runs The Code In That Function Every Frame
	
	
	-- Then We Move Onto The PopulationMetrics:CalculateValues() Function --
	
	
	-- This Function First Creates A Bunch Of 'local' Variables, What 'local' Means Is That 
	-- The Data Given To That Variable Only Exists In That Function Alone And Can't Be Accessed
	-- Or Given Any Data From Outside The Function, I Did This Because I Think Displaying Or Using
	-- The Data May Not Be Necessary For Everyone So I Left It Exclusively In That Function, If
	-- You Want To Use It You Can, I've Left An Explanation At The Bottom Of 
	-- The PopulationMetrics:CalculateValues() Function
	
	-- After Initialising These 'local' Variables, We Move Onto A 'for loop'
	-- A For Loop Is A Function Where The 'number' 'i' In This Case Is
	-- Initialised, Then It States That The Code In This Segment Will Run For
	-- However Large 'self.properties.AllAISize' Minus One So It Does
	-- Not Go Out Of Bounds Of The AllAI Array. 'AllAISize' Is The
	-- Number Made At The Top In The 'PopulationMetrics.Properties' Section
	-- Then Increase By 1 So It Will Go Through The Entire Code At 'i' = 0, Then Once It
	-- Is Done It Will Go Back To The Start Of The For Loop And Then 'i' = 1 And So On Until
	-- It Reaches The Number Value Of 'self.properties.AllAISize - 1'
	
	-- Then I'm Going To Take A Code Snippet For A Better Explanation Here
	
	-- RawHappinessTotal = RawHappinessTotal + AllAI[i].properties.Happiness
	-- AverageHappiness = RawHappinessTotal / self.properties.AllAISize
	-- UIManager:SendToScripts("SetAverageHappinessText", tostring(AverageHappiness))
	
	-- What This Does It Firsts Sets The RawHappinessTotal To Be Equal To RawHappinessTotal
	-- + AllAI[i].properties.Happiness With 'i' Being Whatever The For Loop Has Set It To Be
	-- As It Goes Through And Increases By One And So Accesses Every Entity With The 'AI'
	-- Script Attached, Then It Does The Same For Each Other Emotion, Just With Different
	-- Names But I'm Sure You'll Know What Ones Are What As I've Listed Code Comment Headers Above
	-- Them
	
	
	-- Past That Is The Function PopulationMetrics:OnCollision(interactingEntity) --
	
	
	-- This Function Is Small And Easy, When We Start The Game The PopulationMetrics Entity
	-- Immediatly Collides With The Player And So Gets The Player Entity Which We Store In
	-- 'UIManager' (Named That For Clarity Reasons Stick With Me) Then We Take This And
	-- Use 'SendToScripts' Which We Use For Managing The UI On Screen
	
	-- Then It Initialises A 'Flag' Which Is A Way To Check If A Certain Condition Has Been Met
	-- Which In This Case Is It Checking To See If The Player Should Be Included In The AI Feelings
	-- Array (Array Is A List Of Things), If This Condition Is Met It Calls Back To The self:AddPlayer() 
	-- Function For That To Call The self:Init() Function For It To Recalculate And Gather All Entities
	-- With The 'AI' Script Attached
	
	-- Speaking Of UIManager Feels Like A Good Time To Move Onto That As That's The End 
	-- Of The Population Metrics Script
	
	
	-- UIManager --
	
	
	-- This Script Is Straight Forward, All We Are Doing Is Getting The Entity Of The 
	-- Widgets On The Player, Accessing The Properties For That UI Widget , And Editing The 'signText'
	-- Which Is, The Text That Appears Below The Header And Then Taking The 'Parameter' Which Is
	-- A Bunch Of Letters (A String) Which Is Called 'msg' In This Case And Setting The Text Format
	-- To Be The 'msg' String
	
	
	-- AI --
	
	
	-- This Script Is Relatively Empty Deliberatly So You Can Make The Type Of AI You Want
	-- We'll Take It From The Top Like We Did With The 'PopulationMetrics'.
	
	-- However I Have Made Example AI Scripts For You To Look At.
	-- These Are Called 'Patrol', 'GoToPlayer' And 'GoAndStay'. These Are On The Current
	-- NPC's Entities That Are In The Game.
	-- The Reason I Made Them An Entirely Seperate Script Is Because I Feel Like You Should Make
	-- The Type Of AI You Want To Make With This Tool And These AI's May Not Be What You Want
	-- To Use, It's Your Game After all
	
	-- If You Feel Lost However On Where To Start With Making NPC AI In Crayta, 
	-- Here's A Very Useful, Well Explained Starting Point From Crayta Themselves
	-- https://www.youtube.com/watch?v=FEejt7clJRk
	
	
	-- AI Properties --
	
	
	-- First There Is The 'PopulationMetrics' Referenced Here. This Will Become More Clear As You Read More
	-- But We Are Getting This Of Type 'scriptasset' So We Can Access Some Functions
	
	-- Then Intialise Some Feelings For The AI, We Set Their Happiness, Health, Social And Safety Stats
	-- Here With The 'default' Functionality Or We Can Do It On The Actual Entity In The Entity Window,
	-- It's Your Choice
	
	
	--  Then We Move Onto The Init Function For The AI --
	
	
	-- We Use The Line Of Code 'PopulationMetrics = GetWorld():FindScript("PopulationMetrics")' To Set
	-- The 'scriptasset' To Be Set To The 'PopulationMetrics' In The World.
	
	
	-- And Then We Have The Helper Scripts --
	
	
	-- I Included A Lot Of Example Helper Functions For Setting And 
	-- 'Incrementing' Which Means Reducing Or Increasing A Value By A Set Amount For You To Use.
	-- They Always Reference PopulationMetrics:CalculateValues() To Ensure It Always Gets Updated.
	-- You Can Have It Update In The PopulationMetrics:OnTick() Function I Left Empty But It Would Be
	-- A Lot More Inefficient And A Lot More Noticeable In
	-- Terms Of Performance When There Is More Entities With The 'AI' Script
	
	-- What I Did Not Do Was Make Any Functions For What Would Be The Requirements For Increasing, Decreasing, 
	-- Setting Or Anything With These Functions. I Did This So You Can Decide What They Are Used For
	-- And When They Are Used. I Also Didn't Include Any Code For What The AI Will Actually Do Because
	-- I Feel Like That Shouldn't Be For Me To Decide What The AI Will Do In Your Game. 
	
	-- However I Have Made Example AI Scripts For You To Look At.
	-- These Are Called 'Patrol', 'GoToPlayer' And 'GoAndStay'. These Are On The Current
	-- NPC's Entities That Are In The Game.
	
	-- The Reason I Made Them An Entirely Seperate Script Is Because I Feel Like You Should Make
	-- The Type Of AI You Want To Make With This Tool And These AI's May Not Be What You Want
	-- To Use, It's Your Game After All
	
	-- If You Feel Lost However On Where To Start With Making NPC AI In Crayta, 
	-- Here's A Very Useful, Well Explained Starting Point From Crayta Themselves
	-- https://www.youtube.com/watch?v=FEejt7clJRk
	
	
	-- 'How Can I Add My Own 'AI' Feelings?' --
	
	
	-- You Can Add More Atrributes In The 'PopulationMetrics' Script. This Is Attached
	-- To The 'PopulationMetrics' Entity In The Entity Window
	
	-- You Will Need To Make A UI Widget On The Player, Call It Whatever You Want
	
	-- Then Reference It In The 'UIManager' Script Following The Example Format Shown There
	
	-- Then Go To The 'PopulationMetrics' Script And Go To PopulationMetrics.Properties At 
	-- The Top And Introduce Your Own 'Average MyFeeling'
	
	-- Then Follow The Format As Shown In The 'PopulationMetrics' Script For The Value To Be Shown
	
	-- Then Go To The 'AI' Script And Follow The Format Shown In The Example Format Presented There
	-- This Is So You Can Change The Values Of It Easily
	
	-- You Can Also Add More To The Existing Functions
	-- And Expand On Them, Like Introducing A Get Function!
	
	
	-- 'Can I Use My Own AI Script?' --
	
	
	-- You Can Certainly Use An Exising 'AI' Script, Just Change Any References To The
	-- 'AI' Script In My Tool To That Existing 'AI' Script And Copy My Code In My 'AI' Script 
	-- Into The Existing 'AI' Script
	
	
	-- 'How Can I Add Feelings To The Player?' --
	
	
	-- Add The 'AI' Script To The Player, Remember The 'AI' Script Currently
	-- Is Feelings With Helper Functions, Not An Actual 'AI' That Can Move
	-- Around And Do Things :)
	
	
	-- 'How Can I Add More NPC's?' --
	
	
	-- Copy And Paste Any NPC Entity In The Entity Window. This Will Also The Copied Add It To
	-- The Population The Original NPC Entity You Copied Or If It Wasn't Involved In Any Population
	-- It Won't Be Added Into Any Population
	
	
	-- How Do I Customise The NPC's --
	
	
	-- You Can Customise Any NPC
	-- Easily By Clicking On An Individual NPC You Wish To Customise And Scroll Down
	-- In The Window Below The Entities Window To The 'Customization' Section
	
	
	-- 'How Can I Edit The Values Of The Feelings On The 'AI' Script' --
	
	
	-- Go To The Entity With The 'AI' Script You Wish To Change The Values Of
	-- Click On The Entity And Scroll Down On That Entities Window Until You Find 
	-- The 'Script: AI' Tab And Then Change The Values You Wish To Change By Editing
	-- The Number Next To The Feeling You Wish To Change By Clicking On It And Typing
	-- The Number Or By Using The '-' And '+' Buttons Next To It
	
	
	-- 'How Can I Add A Seperate Population?'
	
	
	-- There Is An Example Which Is Already In Use, See To The 'PopulationMetrics' Script
	-- And Look At The Example 'OtherPopulation' References, Also See To The 'OtherAI' Script
	-- Which Is What 'OtherPopulation' Is Referencing In The 'PopulationMetrics' Script
	
	
	-- Footnote --
	

	-- If You Feel Lost However On Where To Start With Making NPC AI In Crayta, I have
	-- made some basic scripts, you can find them on the NPC's in the Entity Window. 
	-- They Are Called 'Patrol', 'GoToPlayer' And 'GoAndStay' To Get You Started, I've Left Comments
	-- In The 'Patrol', 'GoToPlayer' And 'GoAndStay' Scripts To Explain How These Work
	
	-- Here's A Very Useful, Well Explained Starting Point From Crayta Themselves, I'd Heavily Advise You Watch
	-- If You Want To Make Your Own AI
	-- https://www.youtube.com/watch?v=FEejt7clJRk
	
	-- Not Relevant To The Tool But To Interact With The Door Press 'E' When Close To It To Open
	-- And Close It :)
	
	
	-- See Below How You Can Extend This! --
	
	
	-- Example Uses Of AI Helper Functions -- 
	
	-- AllAI[1]:SetHappiness(4) -- Set AllAI[1]'s Happiness To 4
	-- AllAI[1]:ChangeByIncrementHappiness(4) -- Increases AllAI[1]'s Happiness By 4
	-- AllAI[1]:ChangeByIncrementHappiness(-4) -- Decreases AllAI[1]'s Happiness By 4
	-- print(AllAI[1]:ReturnPosition()) -- Prints To The Console The X,Y And Z Values Of Where AllAI[1] Is
	
	-- You Can Access The Blueprint Here -> https://launch.crayta.com/jmf8r6gj 
	-- And That's Everything, Have Fun!
	-- Lex

return HowToGuide