• entries
44
44
• views
59695

## An example of making a change to Caveman...

An example of making a change to Caveman...

This is a quick description of what its like to make a change to the game.

I just finished the new bandmember AI. Now it was time to make bandmember AI use sprint running speed.

First I checked [color=#0000ff]movement_rate()[/color] to figure out what the speeds were. sneak is 1/2 walk speed. run (its more like cross country jogging)
is 2x walk speed, and sprint is 4x walk speed. walk speed is 1/3 foot per frame at 15 fps (5 ft/sec).

The existing code only supported sprint for the current bandmember (the one the player is controlling at the moment).
and it used the state of the sprint input control (left shift by default) to determine movement rate and fatigue.
What was required was a way to know if any given bandmember was sprinting. this called for a new is_sprinting variable.

I have a checklist i use for adding a new variable to a program:
declare - declare the new variable
init - initialize it
save - add code to save it if needed
change - add code that changes its value
use - add code that uses its value

so first i added an "[color=#0000ff]int is_sprinting[/color]" to the cavemanrec struct declaration. this is the struct that holds all the info for a bandmember.

the code is already setup to init a cavemanrec to zero. so as long as i declare variables so their initial values should be zero, i don't
have to write any new init code. so the code already initialized is_sprinitng to zero (false) automatically.

for load and save, i load and save the individual fields of a struct, instead of just reading or writing the whole struct. that way i can add
variables to a struct, and the existing load code and savegames still work. any new fields are initialized before load. the process is simple,
add the code to save the new variable. run the game. load then save any savegames you want to convert. then add the code to read
the new variable and you're done. the code loads and saves the new variable, and the savegames have been converted to the new
file format.

to change the variable, for the player, i needed to add one line of code to the input processing routine:
[color=#0000ff]if (control_pressed(IN_SPRINT)) cm[cm0].is_sprinting=1; else cm[cm0].is_sprinting=0;[/color]
then i added [color=#0000ff]cm[].is_sprinting=1[/color] before the calls to [color=#0000ff]movement_rate[/color] in the bandmember AI code. This appeared in perhaps half
a dozen places. This made the bandmember AI use sprint speeds.

to use it, i did a search on [color=#0000ff]IN_SPRINT[/color], and replaced:
[color=#0000ff]if (control_pressed(IN_SPRINT))[/color]
with:
[color=#0000ff]if (cm[].is_sprinting)[/color]
this appeared in maybe four places.
that made the movement rate and fatigue code use is_sprinting for all bandmembers (both the player controlled one,
and any AI controlled ones) instead of just using [color=#0000ff]control_pressed(IN_SPRINT)[/color] for the player controlled bandmember.

And thats all there was to it. Don't even think it took an hour.

Now its time to make the bandmember AI play sneak and sprint animations!

Here's the new orders menu code to go with the new bandmember AI

nothing fancy, it shows a menu, "Issue orders to..."
it then sets the orders state or appropriate variable such as sneak_state.

one common game design pattern seen in this code:
populating a menu by iterating though one or more lists and selecting some, but not all the entries, based on some criteria.
and then, once you get the menu pick, you iterate through the lists again to figure out which one it was.

another classic game design pattern:
this is the classic best match search algo used in many places and many ways in many games.
you iterate through a list, finding the entry with the best value of some sort, such as its closest, does the most damage, etc.
you start by setting the best found value to some very bad value, and the best found entry to none. as you go though the list, if the current entry's value is better, it becomes the new best found value, and the entry becomes the new best found entry. when you're done, you return the best found entry, and perhaps the best found value as well, such as closest target, and its range.

This code also includes a simple quick and dirty raypick routine. It starts at the eye point, and uses a unit vector in the lookat direction. it repeatedly adds the unit vector to the point, then checks for intersection with the ground: point.y 200 (in case they aren't aiming at the ground at all!). If it gets an intersection with the ground, it returns the x,z location of the intersection.

You'll notice that in both this code and the AI code, many things need to be done twice, once for PCs, IE bandmembers (cm[]), and once for npcs/monsters (animal[]). Caveman has multiple PCs, like a household in The Sims. The player can tab between them at any time to manually control any bandmember they want. Other bandmembers are controlled by the new AI. So the game has two basic types of entities: bandmembers, and everything else. and it therefore has two entity lists, and more or less duplicate code for each of the two basic type of entites. A C-E approach that used structs for the components common to both could use a single set of code to operate on the structs, irreguardless of whether they belonged to a bandmember or something else. The game uses this approach with requirements structs used by actions, objects, and skills, and with inventory structs used by both bandmembers and everyone else.

## New band member AI code

New band member AI code

Here's the new code for bandmember AI.

In AI terms, this code is a crude expert system:

http://en.wikipedia.org/wiki/Expert_system

it is implemented primarily as a decision tree:

http://en.wikipedia.org/wiki/Decision_tree

lets see... note that some orders are like AI states. B2_BM_run_AI calls badguys_nearby just once as an optimization. set_bandmember_target is only called if and when needed as another optimization. both iterate the entities list. a further optimization would be to iterate the entites list just once, get the index and range of the closest badguy, and then just use that info for badguys_nearby and set_bandmember_target. But for the moment it seems to run fast enough.

## New bandmember AI done

New bandmember AI done

The new AI for bandmembers is done. The new orders menu is done as well. The new AI can deal with being in a shelter, taking fire, being cornered, etc, as well as follow orders or do actions. It now automatically favors missile weapons and skirmish mode before hand weapons and melee mode. Only thing left is to make it use sprint speed, and play the correct animations (sneak, walk, run, etc). right now it doesn't do sneak or sprint animations, as those are new AI capabilities. a simple fix, if sneaking, animation=sneak, else if walking, animation=walk, etc.

It almost worked perfectly the first time. bandmember_is_cornered needed to take into account being inside a temporary shelter. it simply does a check for something_in_way_of_location 4 feet north, south, east, and west of the bandmember. but when they're inside a temp shelter with a BBox radius of 5 or 10, that doesn't quite work so well.... i had to make it check for badguys and leave a shelter before doing common AI such as cornered, collision, recovery, taking fire, nearby threat, etc - not after doing the common AI. i also had to make it leave a shelter before it tried to follow orders when there were no badguys around. and i forgot to call mouse_turn_camera in the raypick code for goto and designate target orders. the new AI code is about 2000 lines of source. the new orders menu code, including raypick code, is about 700 lines of source.

i plan to post some code so people can see how it turned out. basically its as it appears in the pseudocode in the previous journal entry. at the lower levels, some of the existing low level AI routines were suitable for reuse with no alterations, so they were used.

## Issuing orders to party members and refactoring AI...

Issuing orders to party members and refactoring AI...

NOTES:
2. abbreviations used in the pseudocode:
"ret" = return
"dir" = direction
"loc" = location
"CR" = collision recovery

I've been playtesting the game at advanced stages, when you can control more than one band member. This means its time to implement giving orders to party members. The goal is to get the orders and AI to the point where the player, in control of one PC, and able to issue orders to some number of friendly NPCs, can stage an ambush of a target. This requires abilities like use stealth mode, goto location, use missile or hand weapons, attack on my signal, etc. After thinking about it for a while, and going through two design iterations i came up with:
.-----------------------------------------------------------Orders design, version 2.player presses orders hotkey ( default = 'O' )Give orders to...==============EveryoneParty member 1Party member 2Party member 3...Cancellist of party members is all band members, pets, warriors, and companions within 300 of player.Orders...=================goto - location (raypick)use stealth modeuse non-stealth modeuse hand wpn (and melee AI)use missile wpn (and skirmish AI)non-stealth attack (designated or default target)stealth attack (designated or default target)follow - someone (including player - pick list of party members)as you were - cancels ordersrun awaydesignate target (raypick)maintain distancewait here (goto location, location=here)Cancelraypick location: cast ray. location is where ray hits ground: IE when ray.y
.
.
.

The original plan was to modify the AI as follows:
.if unit has orders, do orders // (perhaps with some special cases, like there is a badguy about to attack me)else do normal AI
.
.
.
So then i took a look at what the "normal" AI was. The normal AI was the original quick and dirty prototype AI, which has been modified and expanded until it actually handled over a dozen different types of AI. Its original form was:
.for each unit set target steer move attack
.
.
.
and inside set target, steer, move, and attack, it dealt with the many flavors of AI. On top of this, a setstate/runstate design had been placed, that set the state based on AI type, then called runstate, which made the actual calls to steer, move, attack, etc. Plastering orders on top of all this, and handling the special cases for orders sounded like i would be adding more bad design to existing bad design. Refactoring was called for. This was actually planned all along. the idea was to start with some quick and dirty AI, modify it as needed so its design evolved during development, and then refactor once its desired behavior had been pretty well determined. When i took a look at the exiting AI, i copied it (in pseudocode) into the todo list for the project, so i could get a better handle on what was there. Here's the basics of what i found:
.====== current AI =================================== Bandmember AI---------------------if badguys_near, if inshelter, leave shelter else if doing action, stop actionif not doing action setwpn if in collision recovery, do collision recovery and return set tgt steer move atkelse do action animal AI:----------------setstaterunstate setstate: ----------------if suprised avian, move suprised avian. state=stand, then calls runstate and returnselse if avian predator, avian predator setstateelse if resting, and not done resting, state=restelse if fatuigued, state=restif caveman, setwpnif running thief, thief run setstateelse if approaching thief, thief approach setstateelse if taking fire, taking fire setstateelse if defend location, defend location setstateelse if friendly, friendly setstateelse if hostile, hostile setsatateelse if companion, wartrior, or tamed: companion setstateelse if attack_AI, attack setstate (predators)else if maintain_distance_AI, maintain distance setstateelse if defend_AI, defend setstateelse all others setstate avian predator setstate:---------------------------------set tgt or rng&rhif halfdead, state=runawayelse if taking fire, taking fire setstateelse if resting, and not done resting, state=restelse if fatuigued, state=restelse if not attacking and has tgt within 20, save current state, state=attackelse if attacking but no tgt within 20, state=savestateelse if state=predator hunt if carcass nearby, state= eat kill else if no tgt, state=flockelse if state=predator eat if carcass nearby, state= eat kill else if no tgt, state=flockelse (grazing) if make check, state=predator hunt (time to go hunting!) thief run setstate----------------------if cornered, state=corneredelse if state=collision recovery, do nothingelse set tgt or rng state= thief run thief approach setstate----------------------if cornered, state=corneredelse if state=collision recovery, do nothingelse set tgt or rng state= thief approach taking fire setstate-------------------------if cornered, state=corneredelse if state=collision recovery, do nothingelse set tgt or rng if animal is leaving, do nothing else if tgt is bandmember up a tree and make check, leave else if has tgt if halfdead, state=runaway else state=attackelse state=flock defend location setstate--------------------------------if cornered, state=corneredelse if state=collision recovery, do nothingelse set tgt or rng state=attack tgt closest to location friendly setstate----------------------------if cornered, state=corneredelse if state=collision recovery, do nothingelse set tgt or rng if talking to bandmember, state=stand else if CRH caveman (a caveman at a shelter) if within 500 of home if >50 to home, moveto home else if has tgt 100 from ower,state= moveto owner else if has tgt, state=attack else if talking to bandmember, state=stand else if > 20 to owner, state=moveto owner else state=stand attack setstate (predators)--------------------------------------if cornered, state=corneredelse if state=collision recovery, state=collision recovery (no change)else set tgt or rng if animal is leaving, do nothing else if tgt is bandmember up a tree and make check, leave else if state=attack if has tgt if halfdead, state=runaway else if tgt rng >20 flock else (no tgt) state=flock else if state=predator hunt if has tgt if halfdead, state=runaway else if carcass nearby, state=eat kill else (no tgt) if halfdead, state=runaway else if carcass nearby, state=eat kill else state=flock else if state=eat if has tgt if halfdead, state=runaway else if rng 20, tgt=ownerelse tgt=set friendly tgt (closest wild or hostile, not obscured by coverage diue to range)if tgt rng to owner > 20, tgt= none set wild tgt defend location-----------------------------------targets closest to defend location:detected bandmember-or-not subdued or captured animal, not of same type as attacker. set wild target----------------------targets closest:detected bandmember, not obscured by coverage due to range-or-not subdued or captured animal, not of same type as attacker, not obscured by coverage due to range set predator tgt---------------------targets closest:detected bandmember, not obscured by coverage due to range, if a baseline caveman has same or less HP than attacker (predators dont target animal types with more hit points than the predator has)-or-not subdued or captured animal, not of same type as attacker, not obscured by coverage due to range, and has same or less HP than attacker (predators dont target animal types with more hit points than the predator has). runstate---------------if in collision recovery move_collision_recovery return stand: if avian if airborne, land else recover fatigueelse recover fatigue wander: (a "wander to" location is randomly generated and stored when this state is first entered)if avian, calc rel heading to wander to locationsteer_animal3moverun run away:steer_animal3moverundo_animal_atk attack, predator hunt:if avian, run avian attack AIelse calc heading set rng steer animal3 new_moveatk do_animal_atk eatkill:do eat kill cornered:do_cornered def loc:do def loc moveto home:do move to home friendly atk:calc headingset rngnew steer animalnew move animaldo animal atk thief approach:calc headingset rngnew steer animalnew move animalif rng= limit, end collision recovery land----------move animalif alt
.
.
.
the original plan for refactoring was:
at the highest level, i wanted two routines: setstate and runstate.
at the lowest level, i also wanted two routines: turn(amount) and move(amount).
Great! Then it was just the stuff in between that i had to worry about.

So i pseudocoded a setstate/runstate version of the AI, improving the designed behavior at the same time. This wasn't that hard. setstate simply called a custom setstate routine for each of the types of AI, and runstate was largely unchanged. I also separated the avian from the non-avian runstates, as they do differ somewhat. I called the new AI api the "BB " api, hence the BB at the beginning of function names and predefined values.

Here's the result:
.
.
.
Then it occured to me that the setstate/runstate pattern is sort of yet another example of unnecessary deferred processing. if i'm in setstate, and determine a desired state, right then i know which code in the case statement in runstate to run, so why not put the code in a routine and just call it right then and there? so the basic architecture of the AI evolved again. The follow is an example of the basic design iterations:
.ORIGINAL WAY:for each unit set tgt (based on unit type) steer (based on situation and AI type) move (based on situation and AI type) do attack (if badguy in strikezone, start attack)SETSTATE/RUNSTATE WAY:void setstate{if (condition A) state=Aelse if (condition B) state=B...}void runstate{switch(state)case A: // code to handle state A breakcase B: // code to handle state B break...}NEW WAY:void run_AI{if (condition A) dostateA()else if (condition B) dostateB()...}void dostateA(){// code to handle state A }void dostateB(){// code to handle state B }
.
.
.
and here's the new AI, ready to cut and paste into the code and translate from pseudocode to real code. this version i named the "B2" api, so
its functions and pre-defined constants begin with "B2". As i wrote it, i split it up based on call hierarchy, just to see how many levels of AI there were. Turns out there are seven levels of AI, with run_AI at the highest level, and calc_amount2turn, turn_unit, and calc_dir2loc at the lowest level (move_unit ended up at the second lowest level).
.
.
.
once this is implemented, audio and action animations are the only really big things left to do.

## Progress report, August 28th, 2014

[color=#ff8c00][size=7][font=arial]Progress report, August 28th, 2014[/font][/color]

Playtesting and tweaking continues. As they say "God is in the details!" Adjusting: collision radii, clip radii, research times and chances, gathering times and chances, etc. The Avian AI is still exhibiting odd behavior at times. Bandmember AI (AI that runs a PC when the human player is not controlling them) needs a number of minor adjustments.

Along with the usual "how things are going" info, i'd like to touch on a few ganmedev related topics that have come up since the last progress report.

[color=#ff8c00] [font=arial]Project size and scope:[/font][/color]
Caveman 3.0 is big. Probably the biggest game i've ever made. Probably bigger than one person ought to try to do by themselves. I'm not saying it can't be done, its just a HUGE time investment for one person. If you're a lone wolf or small team, think long and hard before you take on a big project. If you do decide to go for it, it might be a good idea to build and release in stages. Start with the core game, then expand in future versions. Big projects that take a long time can lead to my next topic...

[color=#ff8c00][font=arial]Procrastination and burnout:[/font][/color]
About 2 years into the project, i found my productivity dropping. Team burnout was the cause. In my case, i reached my limit at 27 months of continuous maximum effort. So i'd take a break. But even after extended breaks, i was still not motivated. While surfing the web i came across "7 causes of procrastination and what to do about them". Turns out my cause was #2, burnout. So i switched gears a bit and spent some time evaluating other games, and watching tv and movies related to games i'm working on. I continued to work on Caveman, but not every waking moment. Sure enough, after a while, i was thinking about the project again while playing another game or watching tv or a movie, and soon after that i was motivated to get back to it fulltime. lessons learned: you gotta take a break every once in a while, and don't be in too much of a hurry to get back to work, wait until once again its what you really WANT to do. Spending time watching tv and movies and evaluating other games leads to my next topics...

[color=#ff8c00][font=arial]Faith:[/font][/color]
[color=#ff0000]WARNING: if you have never seen korean dramas or korean historical dramas, they are quite addictive, if you get hooked, don't blame me![/color]
One of the things i did while taking a break was i watched "Faith" for the second time all the way through. Its a korean historical fantasy drama set in the 14th century. A big budget production. And its got it all: action, martial arts, intrigue, drama, medical drama, fantasy, time travel, romance, comedy, you name it! All the production values are top notch: writing, costumes and props, sets, settings, special effects, anamie, subtle incorpration of fantasy elements in a beliveable way, casting, and acting (from what i can tell, i don't speak korean). The entire story is told in a one year long series, 24 one hour episodes, about the same as a long mini-series in the US. I can not recommend it highly enough if it sounds like your cup of tea. goto hulu.com and do a search on "Faith"

[color=#ff8c00][font=arial]A lot of my time playing games is spent waiting...[/font][/color]

The Sims: you queue up a bunch of actions, then you wait. or you wait while your sim sleeps or is at work. dont even get me started on the 4 minute load times for a small savegame file! And you can't speed up the game by much. normal speed appears to be something like 1 second of real time = 1 minute of game time. fastest speed is perhaps at most two or three times that.

Skyrim: not so bad, since its basically a big shooter. travelling to undiscovered locations for a quest. turn on continuous move and wait. and then there's the load screens. i actually find myself deciding what to do based on the fewest loadscreens required. IE i might sell or store an item at one location vs another because its 4 vs 6 loadscreens to get there. when loadscreens affect player gameplay decisions in this manner, it CAN'T be a good thing.

Rome II Total War: much of my time is spent waiting for other factions to take their turn, or waiting for troops in battle to march across the field to the enemy. And like the sims, the battles cant be sped up by much more than 2x.

Simcity: waiting for time to pass. again, you can't speed up the game by much.

[color=#ff8c00][font=arial]Low framerates:[/font][/color]
I was shocked to find out how low the framerates were for some games on my PC. The SIMs 3 in native resolution and lowest graphics settings clocks in at a whopping 9 to 12 fps! The graphics benchmark from Rome II Total War at lowest resolution and graphics setting can only manage 12 FPS. And this is on a PC that came out at the same time as these games. By comparison, Caveman 3.0 can do 15,000+ non-instanced meshes at 15 PFS all day long. And it can do over 100 animated charaters at once onscreen at 15 FPS. A typical complex scene (~10,000 meshes, perhaps 20 animated charaters) runs at about 20FPS with the framerate limiter turned off.

[color=#ff8c00][font=arial]Responding to input immediately:[/font][/color]
I've noticed a number of places in a number of games where the only response to input is a momentary or extended freeze or lockup. Saving in Rome II comes to mind. You click the OK button, and the game frezees. No "Saving game..." message or anything. The only signs of life are the hard drive light blinking. After some number of seconds, it comes back with a game saved message. I've also noticed a number of games are rather sluggish in response to input, as though clicks are being sent to some messaging system for processing by other components, instead of being handled immediately upon detection. Obviously i'm not privvy to the inner working of these games, and can only guess that its some morass of message queuing, multithreading with stalls, unoptimized middleware, and slow garbage collectors that causes this. divvying things up and passing messages everywhere may be a neat way to organize code, but it also adds overhead. i'm of the old school when it comes to how responsive software is: "If the task is not completed by the time i lift my finger from the key or button, its too slow!" perhaps this should be modified to "if it doesn't at least respond somehow by then, its too slow".

[color=#ff8c00][font=arial]The fastest code:[/font][/color]
"The fastest code is code that never gets executed". We've all heard it. Sure, it sounds great, but turning off code usually isn't a practical speedup. While playtesting, I've constantly been plagued by the fact that the simulation simlpy can't run blazingly fast and do complex AI for lots of targets all at once. Because of this, when i get an encounter, i usually move on until the animals are removed from the simulation due to distance. Then i get back to making a spear or whatever, once the simulation is running blazingly fast again. The obvious answer was further optimization of the AI. But i'd already been there and done that. Iterating through the list of active entities to select a combat target is the bottleneck, with no obvious solution in sight. Nothing less than a pardigm shift would change things. So i changed the rules! You can now only accelerate the game faster than 128x if there are no hostiles around. and at speeds above 128x it doesn't update non-hostiles at all (the AI code doesn't run at all). This simple rule change makes all the difference in the world. Now you can fast forward through actions with non-hostiles nearby at blazing speeds, and you still get full tilt AI when hostiles are around - having your cake and eating it too, very WITH my religion (as opposed to being against my religion).

[color=#ff8c00][font=arial]We now return you to your regularly scheduled progress report:[/font][/color]

recently done:
* increased sleep time by about 10%
* gifts to cavemen increase relations by twice as much.
* fixed: cant rest & heal in temp shelter w/ bedding when sick but not injured.
all rest and heal action triggers now use a single generic try_rest_heal() routine that lets you rest and heal if you have damage or are sick.
* fixed: getting encumbrance fatigue when not moving or engaged in sedentary activities
* added button graphics to view inventory and view help
* rest and heal now shows damage as well as progress
* added eat/drink actions inside shelters
* find reeds: doubled time required, cut chance in half
* fixed: doesn't moves followers when cross-country movement stopped due to encounters, etc
* fixed: companion's model and textures not copied to new bandmember when they join your band
* fixed: companion's 3rd interest not copied to new bandmember when they join your band
* fixed: companion's social not set when they join your band. now set to 100.
* turned off damage display over bandmembers
* AI recalcs best tgt every 2 secs, not every 5.
* fixed: doesn't draw rain/snow outside temp shelters
* fixed: new bm not set to alive when companion joins band
* increased MAX_RESOURCES in a map sq from 1000 to 2000
* cut crh resource reduction chance by 50%
* fixed: added renew_resources() to change_the_map(). 10% chance per day for depleted map sq to renew back to MAX_RESOURCES.
* added "issue orders". remapable "o" key input. orders menu: follow me, attack, and as you were.
* added "make sacrifice to earth godess gah" to rocks menu. volcanos only was too hard.
* sucessful sacrifice actions now boost god relations by 30. was 5 for fire, and 20 for all others.
* increased local automap range from just the players current local map sqaure (100 foot) to a radius of 2 local map squares around
the player's local map sq. range before: 0-100 feet. range now: 200-300 feet.
* game now runs fast with non-hostiles nearby! wont go faster than 128x with hostiles alive. doesnt run animals at speeds above 128x.
* button graphics for select_object screen
* button graphics for shift_select_object screen
* button graphics for trade screen
* increased collision rad: gt ground sloth
* increased collision rad: short faced bear
* fixed: animal encounters: start location not normalized
* fixed: caveman encounters: start location not normalized
* make bedding: shows progress %
* make bedding in shelter: shows progress %
* fixed: draws plants over bedding
* fixed: regen terrain chunks when build temp shelter
* fixed: regen terrain chunks when build bedding
* fixed: search dead CM: take one: doesn't remove item from list!
* fixed: action msg for making fire is messed up
* increased clip rad: world objects (due to temp wood shelter).
* increased action area for selecting temp shelter.
* 1 hand stone hammer: doubled time to find, cut chance to find in half.
* added /d command line switch: enables display of debugging messages as the program starts up.

beta 11 has been posted.

[font=arial]http://rocklandsoftware.net/beta.php[/font]

[font=arial]Thats all for now![/font]

## Progress Report - July 21st 2014

Progress Report - July 21st 2014

Beta 9 has been posted to the website, with a new download page:

http://rocklandsoftware.net/beta.php

I could really use some feedback on the game, so please, check it out! Its just a 60 meg download, and should provide about one evening's worth of gameplay.

Beta 9 now includes such niceities as real setup and uninstall programs.

Still needs audio and an opening animation. But I found a copy of caveman 1.0, complete with all the original wav files! And i still have source code for version 1.0, including the music player code. X Audio 2 based code is already in Caveman v3.0, - ready to go - just add wav files and stir!

I'm thinking I'll hold off on offspring, dinos, modern, an aquatic animals due to the time required to create the additional content (models, meshes, textures, and animations for babies, children, dinos, modern animals, and aquatic animals).

Audio and some serious play testing seems to be the next most important thing on the to do list for the project.

I also added a "quick tour" of the game to the website:

http://rocklandsoftware.net/caveman-tour.php

That's all for now!

Remember - keep your eye on the prize! Twice as important when its a big prize and takes a long time.

Hailing frequencies closed...

## Caveman v3.0 progress report, April 20th 2014.

Caveman 3.0 progress report April 20th 2014

Work on Caveman continues. Its down to high level features and polishing. Currently, the quest generator is under construction, with 14 types of quests implemented so far.

Also the Beta has begun.

Check it out and let me know what you think!

Please send feedback to rocklandsoftware at gmail dot com. Thanks!

If you find its your kind of game, I'm still looking for more play testers.

Recently done:

* added chance to discover you're lost while travelling cross-country, and stop.
* "view model" assigned to F4 by default
* "save game" assigned to F5 by default
* move slower uphill and faster downhill. speed based on slope.
* cut number of rocks in rocks terrain in half
> hit points
> caveman encounter chance
> animal encounter chance
* pushes action (saves it) when interrupted by sleep, resumes action when you wake up.
* number keys for select wpn
* added ability to yield while in combat.
* NPCs switch to "stand around" AI when combat ends.
* more realistic gear loadout for npc's, including small chance for artifact.
* fixed: hut NPC encounters were not setting NPC's house_index for new npcs.
* fixed: cliprng not set for hut doors and centerpole.
* demo version
* beta version
* huts and caves are no longer created in canyons
* cross country movement is now at walk speed.
* system requirements are now displayed when unable to create d3d device due to
pc not meeting minimum system requirements of 1600x900, 32bit ARGB, 24 bit depth buffer.
* improved frustum culling. terrain chunks behind player are
no longer culled in 3pv max zoom out looking straight down.
* fixed: swamp ground texture wrong.
* fixed: skills display, throwing rock atk text too wide
* fixed: skills display, throwing axe atk text too wide
* dead npc: the game now changes wih (weapon in hand) to hands if the player takes the npc's wih.
* more trees in northern savanna
* clear all terrain chunks if player doesn't take over abandoned hut (makes hut disappear)
* fixed: stream quads don't quite reach to bank (about 1" short)
* fixed: check fire - shows fuel left
* fixed: recover from illness too fast?
* fixed: fruit spoils too fast?
* double the rate of fatigue increase when sprinting
* added double quote to caveman font
* fixed: local map scrolls a little too fast
* speedups: indexing huts, indexing caves, updating crh
(cave, rockshelter, hut) stufflists (what they have to trade).
* new all-in-one "start new game" screen
* improved heightmap formulas for flowing water. reduced z fighting
where size of flowing water changes at map square edges.
* fixed: 1pv 1 hand stone hammer male atk ani stone not drawn in hand correctly (off by 2 inches)
* added pound sign to caveman font
* fixed: female vest armor too small
* forrage action: now shows food stat
* ability to block all the time, even when you weapon is not drawn.
* sprinting and fatigue modeling for npc's and animals.
* draw shield in 1pv block ani
* tutorial
* gamespeed 5. 1 screen per hour, does not draw the scene. therefore no need
to generate terrain chunks for each screen if travelling cross country.
* fixed: river action area too samll
* full fatigue no longer triggers rest action. now it reduces player to walk speed.
* added animal and NPC attack fatigue modeling.
* gamespeed 6. one screen per hour, does not draw the scene. does not run animals or
npc's. only available when no badguys are nearby.
* questgen: 14 types of quests so far.

time to implement the next type of quest!

## The building of caveman part 4 - The Z game library

The Building of Caveman - Part 4

Z3D - The low level generic game development library

So far i had a wrapper for the dx9 fixed function pipeline, and a
render queue and state manager desigend to feed data to the pipeline
in optimal order for fastest performance. The render queue allows
the game to make drawing callis in a more of less arbitrary order.

But it takes much more than a render queue and state manager to
build a game. additional componets required included:

* fonts
i went with d3dx fonts at first. later, i switched
to a custom font using faster d3dx sprites.

* materials
d3d lighting equations are complex and powerful.
i decided to control lighting primarily via materials to simplify things.
the game uses a database of about 8 materials. everything from dirt to
emissive beacon. Some materials such as plant specular and clouds vary
depending on time of day. A fair amount of time was spent tweaking the
lights and materials for the best lighting behavior possible with the
limited capabilites of dx9 fixed function.
A side benefit of controlling lighting
through materials is the ability to adjust brightness by simply scaling
material values. This avoids the "washed out" look of using gamma to

* textures
i created a textures database. a simple array of d3dx9 texture pointers.
It supports solid and alpha tested textures with or without mipmaps,
as well as alpha blended textures with mipmaps.
textures are refereced via their array index (Texture ID).

* meshes
again, a simple database. d3dxmesh pointers at first, later replaced by
a struct with a vb, ib, numverts, and numtris. references are via
index # (Mesh ID).

* multi-mesh models
since the game uses one texture per mesh for speed, two textures means
two separate meshes. so a rigid body modeling system was created.
It was also required for the rigd body charater animation system.
Caveman uses rigid body animation instead of skinned meshes.
This allows it to draw about five times as many characters on
screen at once.
So a models database was required to hold the model data.
its an array of structs, obe for each type of model.
a struct contains info like the number of limbs, and the mesh, texture,
scale, location, parent, etc, of each limb.
As with all the content databases in the game, reference is via
array index # (model #).

* animations
animations are keyframe in style, and manipulate the limbs of
a multi-mesh model. the game has a database of animations (array
of structs). each struct contains info like number of keyframes,
limb rotations for each keyframe, number of frames between keyframes,
etc.

* animation players.
an animation player takes an animation, and a model, and an animation
frame counter, and tweens the model for drawing. animation players are
assigned to bandmemebrs, animals, and npc's when they start an animation.
the game contains an array of 200
animation players - an "animation manager".
a animation player is just a struct with info like an "active" field,
animation #, model #, and framecounter.

* sprites
d3dx sprites, with some wrapper routines to provide an api like:
drawsprite x,y, x scale, y scale
where x,y is the upper left corner, and the scale values are
0.0 through 1.0 inclusive. sprites use the textures database.

* gui components
a popup menu, and a text entry dialog box. the popup menu can
double as a message dialog box, just make the last option "ok",
and repeat until they select "ok". everything else is custom
screens done with sprites and fonts. thankfully there are very
few custom screen required - less than a dozen. menu() and
getstring() handle all the rest. There is also a text file
viewer for help. the menu system uses an array of strings.
the game calls Znewmenu(title_string) to begin assigning text
to get a menu pick (option #).

* lights
Caveman tries to do simple to implement and fast yet realitic
lighting within the limitations of DX9 fixed function. It uses
a single directional light for sunlight and moonlight. point
lights with a small radius are used for fires and torches. These
are the only lights used. sun and moon light are varied based
on time of day and cloud cover. Lighting is primarily controlled
via materials, with an overall lightness_factor() being the only
variation in actual light settings, and then only for the sun/moon
light. Light settings for rendering scenes were determined first,
then materials were adjusted to get the desired behavior, with
new materails added as new behaviors were required. Light settings
are heavy on the diffuse, and very light on the ambient for a more
realistic look.

many other low level genric routines are reqiured for games:
math functions
file i/o
high resolution timers
keyboard input
mouse input
etc.

in the past, i've collected such routines into a generic game
development library that i've both used in-house and sold publicly
(passes the dog food test! ).

so i proceeded to round out my graphics code with the additional
generic low level stuff required. The result is the latest
incarnation of Rockland Software Productions game development
library. This version is called the Z game library.

the Z3D module is the main module, containing the graphics and
generic game code. There's also an audio module, and a
modeler / animation editor module. The are also experimental
modules for fonts, gui components, a "game engine", an entities
list with AI routines, and a directx 11 version of the Z library.

here's the API for the Z3D module:

Note that Caveman uses its own custom target list, AI,
skybox, mouse aimed camera, fonts, screen dump, FPS meter,
ground drawing code, and buttons. The genric GUI components
are only used for error messages during startup before going
fullscreen 3d.

part 3:
https://www.gamedev.net/blog/1730/entry-2259520-the-building-of-caveman-part-3-getting-a-handle-on-directx/

## The building of Caveman - Part 3 - getting a handle on directx...

The building of Caveman - Part 3 - Getting a handle on directx

Getting up to speed:
So i was going to be using directx and visual studio c++. All fine and good,
but i hadn't written a line of code in something like six years! So, first
came console mode hello world. then came directx fullscren mode and clearscreen.
then came the usual beginning direct programs. draw triangle. draw
textured triangle, etc. took 5 programs over maybe a week to get back up
to speed enough to proceed.

Getting a handle on directx:
The api for the fixed function directx 9 pipeline is not what i'd call clean.
So a thin wrapper api was called for. i did a lot of research in order to figure
out how to make the pipeline run fast. what the pipline likes to see in the way
of calls, and what games tend to do in the way of calls are rather different.
The pipeline likes to draw large numbers of triangles with the same mesh, texture,
material, and other settings all at once. Games however, tend to draw objects
in a scene which can be made up of many different meshes, tetxures, materials,
settings, etc. The solution was a render queue. I call mine the drawlist.

Basic rules to go fast:
as a result of my research on how to make the pipeline scream, the following
1. one texture per mesh
2. all textures 256x256
1024x1024 backgrounds are the only exception to mantra #2.

Structs, Arrays of structs, Records, Databases, and Lists:
I've disovered that games run on databases. the list of actvie entities is a
database, for example. all content assets of a given type might also be
considered a game datatbase. i usually implement my databases as arrays of
structs. required size is usually known, so a static array of structs is simple,
fast, and adequate. i will usualy refer to them as datbases or lists, rather than
arrays. and i usually call a struct in an array a datbase record. in these posts,
i will use the terms array, list, and database interchangably. and i will use
struct and record interchanably as well.

The drawlist (the render queue):
It was almost 2 years from the time that i wrote the first drawlist code to the
time i first heard the term "render queue". you learn something new every day!
the drawlist is a list of what to draw. you throw meshes (with textures,
materials, transforms, settings, etc) at it, and it draws everything in optimal
order for you. there's not much to it, a struct with all the info to draw a
textured mesh, like meshID, texID, materialID, mWorld, flags for alpha test,
cull, clamp, etc. these are kept in a list. there's also a 3 dimensional index
into the drawlist. its a list of all the textures, and for each texture, a list
of all the meshes that use that texture, and for each mesh, a list of the indices
into the drawlist of the individual records to draw using that mesh and texture.
Drawing calls add a record to the drawlist and its index. draw_drawlist() goes
through the index, drawing everything in (texture, mesh) order. the drawlist
includes a built-in state manager for drawing. the state manager filters out
redundant state changes such as changing mesh, texture, material, or settings,

so the render queue (drawlist) and the wrapper api made directx petty easy to
work with, and run fast. Now it was time to build the game.

part 2:
https://www.gamedev.net/blog/1730/entry-2259488-the-building-of-caveman-part-2-what-to-build-and-tool-selection/

part 4:
https://www.gamedev.net/blog/1730/entry-2259583-the-building-of-caveman-part-4-the-z-game-library/

## The Building of Caveman - part 2. What to build, and tool selection

The Building of Caveman - part 2.

What to build, and how?

What to build? thats the first of a million questions to be answered when
building a game.

Well, the answer turns out to be pretty simple:

you build what you want to play, that somebody else hasn't already built
for you.

odds are, if you think its cool enough to play that you'd go through the
effort of building it just to play it, then maybe other people might
like to play it as well.

in my case, it was pretty easy. i'd already made over a dozen games over
the years. some hits, some ok, some that didn't sell much at all.

so you go with what works.

the line of thought was: "well, my biggest hit was probably Caveman,
so i probbaly ought to do that first."

So that settled what to build: you lead with your strong suit, your
flagship product.

Now, how to build it:

Platform:
PC. bigger installed base than mac and linux. insufficient
manpower (i'm an army of one) to support multiple platforms,
so PC is it. moble etc isnt even an option ue to the size of the
game - at least at first - pc alone is plenty of a challenge.

Language(s) and libraries:

WHATEVER:
1. HAS THE CAPABILITIES REQUIRED
2. RUNS FAST ENOUGH
and
3. WILL REQUIRE THE LEAST LEARNING AND DEVELOPMENT TIME

in my case, that was procedural ADT C++ code (look it up!), and DX9
fixed function. i'd been coding C/C++ games since before OO syntax,
and didn't really need the OO language extenstions, thus the
procedural ADTs. And Caveman has a paleolithic setting with no
magic or fantasy elements, so not much in the way of special effects,
smoke, flames, clouds, thats about it. so all i needed was
aniso-mipmapped textured meshes, with a little alpha test and alpha
blend. I do use a 2 stage textre blend for snow on the ground but
them or needed them yet in fact. truth is, i'm a little scared
to get into shaders for fear i'll like it too much. the mere
concept of such power to "party on the bitmap" is...
intoxicating .

At this point i should mention that Caveman was developed on a
budget of $0. one baseline$400 pc (no graphics card), and
internet access, thats all you get to work with. no money for
tools, content, middleware, etc.

Compiler:
ms visual studio of course. i started with basic, then pascal,
then watcom C, all in the quest for speed. sometime in the mid
90's microsoft got a clue and added the compiler optimizations
required for games to the free version of MC C++. And directx
tends to work better with ms c++ than with some other compilers.

3d modeler:
truespace rosetta 7.61 beta
1. its free
2. used to be the next best thing after 3dsmax
3. full directx .x save capabilities built in. no conversion /

2d paint programs:
paint.net and "free clone stamp tool".
both are free. paint.net has the basic capabilities of
photoshop. clone stamp takes up the slack. a really awesome
little texture painting program.

Audio tools:
TBD (to be determined)
i have xaudio 2 up and runnning but so far all it does is
play "time to relax", track 1 from the album "smash"
(as i recall) by the offspring as a test. it was the first
wav file i came across on my hard drive. the music for the
game is pretty simple, tom toms and flute for atmosphere,
funky beats reampped to jungle drum kits for combat. and i
have the general 6000 series 50 cd sound effects library
from Sound Ideas for foley sfx. but i gues i'll have to
build another bow. the sound of a primitive bow firing was
the only effect i had to make myself for the original version.
to do it, i made a 7 foot long bow, with fishing line for
the bowstring, and relatively straight wood sticks for
worth of content at wolf's originl price point of $20), and if they liked it they paid for the full version. sounded good to me. but my game was a mission based starship flight sim, not a level based shooter. so i limited it to 4 types of missions (out of 10) and 10 missions completed max (vs unlimited). then i posted it to the local bbs's. about 3 weeeks later someone uploaded it to AOL. i didn't even have an account. it became a top 10 download of the week on AOL, with over 10,000 copies downloaded the first week. all thanks to good copy in the file description (marketing, marketing, marketing!), and a cool game to back it up. for a flight sim it was pretty easy to play, as you could automatically lock onto any target with the computers, and fly to it or attack it. SIMTrek was followed by many other games, apps, and utilities on and off over the years (this is the fourth time i've started or re-started my software company). i was blessed with a second hit when i restarted Rockland Software Productions for the second time in 2000. Caveman v1.0 was picked up by the local NBC news in Washington DC (where i live) as a last minute xmas gift. response was so great it crashed the website! about 3 years later, i got cracked by a team out of eastern europe. the cracked version of Caveman v1.3 was posted on a warez site in Africa, hosted on servers in Russia. it was probably on other warez sites as well. losses were so bad, i had to fold the company. in 2006 i started developemnt of caveman 2.0, a full first person view virtual world implementation of the game, and almost finished it. but i lost funding and the project had to be abandonded. in 2012 i re-started rockland software productions for the fourth time. so i was (re)starting my software company from scratch. what to build? this is where the story of the building of Caveman begins... part 2: https://www.gamedev.net/blog/1730/entry-2259488-the-building-of-caveman-part-2-what-to-build-and-tool-selection/ , ## A day in the life... A day in the life... This will give you an idea of what its like to be an indie. Tasks to be done on the project go on the "todo list". once they're completed, they're moved to the "done list". here's the "done list" for Caveman for the last few days: march 15th:* draw prairie better - need ref photos. need prairie grass textures. made new grass mesh, new grass textures, new grass ground tiles, new grass drawing routine. * draw savanna better - need ref photos. need red dirt tex. need brown grass tex. need acacia tree meshes. need acacia tree bark texxture. need acacia tree leaf texture. made acacia tree leaf texture, tree turnk mesh, and tree model. added ability to add a model to a chunk. added new draw tree routine. march 16-17th:* need to model getting lost better? get lost too easily? adjusted chance to get lost. some difficulty generting a low enough probabiltity check, as the dice() funtion can only go down to 1 in 32K chance. the odds are more like 1 in 2 million (or billion?) per frame.* tried numerous (six?) methods for drawing rain, including particle system. still no satisfactory solution. march 18th:* fixed weather engine (hopefully). world now split into 3 climate zones, hot, med, cold. sand, jungle, savanna only found in hot zone. limits placed on "temp at cm0", based on climate zone. so no snow in hot zone etc. * snow in jungle - weather engine* different weather for different areas? improved weather engine* snow in desert - weather engine* snow in savanna- weather engine* wood spear male 1st person atk ani - already fixed* water quads - gaps at seams - already done* water quads - increase clip rad - already done* clouds move too fast? cut speed in half* gap in ground mesh where flowing water meets ocean. need to change heightmap near ocean. if at edge near ocean, heightmap = lerp from std heightmap to zero. fixed. heightmap was returning water edges with no seam fixup. now it does water heightmap, then seam fixup.seam fixup already accounts for ocean.* fix heightmap where flowing water crosses map square edge. was caused by no seam fixup. now it does seam fixup.* z fighting where flowing water meets ocean. made hm_flowing_water_edge routine that comes before (overrides) seam fix where water crosses map edge.* ocean color is darker than flowing water. generate ground mesh: ocean was using ground material, not default material.* add impass mtns to player map when they come into view* automap the local map more often, spinting skips some local map squares.* butcher animal - show % done. already done.* should not get fatigue watching clouds etc. - you don't. its damage and encumberance doing it.* animate player run (walk, actually) in cross country 3pv* clouds move too fast, shouldn't move as fast as wind? cut speed 50%. march 19th:* player jump ani in 3pv* 3pv, jump: make model go up/dn.* fixed: forward motion stops while jumping during continuous movement.* jump: restart sneak ani from the beginning each time they start a jump.* impass mtns - show msg, improve hgt map. already done.* game starts in winter! fixed, starts in spring. * stargaze, etc - show mood during the action. did stargaze, watch clouds, sing, dance, play drums, play flute, and daydream.* draw player upatree in 3pv.* dont draw player upatree so high in a tree in savanna. upatree increases y by 20. this is done many places in the code, hard coded as 20. making it a variable would be major work. probably not worth it. * superclip4 was clipping bandmember upatree. turned it off for drawing current bandmember upatree.* move upatree height down to work with acacias, as well as taller trees. so that hard coded 20 became a #defined constant after all.* disable move, climb, sneak, and jump when upatree* moving manually, fatigue hits 100%, triggers rest action, speed doesn't drop back to normal at end of rest action. fixed. it was pushing donothing on the action stack. when rest ended, it would pop donothing and not change speed, instead of setting action to donothing and speed to normal.* increase clip rad of acacia tree model. same issue as 3pv clipping of player up a tree? superclip not working for objects below the camera?* sleep doesn't take long enough? increased base time from 1500 to 1700.* green sky, just before noon? fixed. limited r,g,b to 255. brighter sky was probably causing wrap around.* should rain wake you up? rain and snow now wake you up when it starts to rain or snow.* rest - if no action afterwards, set gamespeed to normal (1). already done.* use old flat heightmap for swamp* rest action: show fatigue %* ACTION AREA FOR RIVER NOT WIDE ENOUGH? fixed. increased from 20 to 30 radius.* river quads dont quite reach to edge of river bank. fixed. increased draw rad from 30 to 40.* small deer are too small and slow. fixed. animal 28. scaled model by 1.5. changed texture and moved horns so it wasn't just a smaller version of animal 11. increased speed to .4* improve heightmap where flowing water crosses map edges.* more stars at night - double up the textures march 20th:* savanna being generated in bottom 1/2 of map, not bottom 1/3!* need non-tropical savanna. same as savanna, appears in northern 2/3 of world, uses regular tree models.* regen terrain chunk if waterhole or creek goes wet/dry. covergae can change too. and other types of water. 2 choices: 1. regen map sqaures that change. 2. invalidate all chunks when the map changes, forcing regen of all chunks. made it init_chunks after change_the_map. no problem. runs plenty fast. didnt even notice it re-generating all visible chunks. march 22nd:* input mapper. can remap input controls to any key or mouse button. added new playetest menu, triggered by alt-F12. moved playtest hotkeys (including old playtest menu) to new playtest menu. pain in the ass. lot of typing. 2 days. 33 input controls, mappable to any key, or L or R mouse button. needed a routine to return the name of a key/button. numbers, function keys, and letters were easy. everything else required a huge switch statement. same thing when checking what key they pressed. tons of typing.* falling snow needs help - need to get online. current effect is passable. good enough for now.* rain: need better rain effect - need to get online. made rain tube w/ endcaps. tube is cylindrical mapping scaled 30x10, endcaps are planar mapping scaled 10x10. uses 4 animated textures in round robin fashion. tube is unit size, scaled to 3 ft height and diameter around the camera. march 23rd:* improved caveman font* dropped lit torch - animate flames !use torch model. save head texture. change head texture to flames, and also draw a quad with flames. similar to flaming javelin. restore head texture when done.should a lit torch go out if you drop it? - No.make flaming torch model - animate the textures before drawingdone. model already made. animated the textures, set material to beacon.* crc check for corrupt savegame files. give option to load backup if corruption detecteddid checksum. added to z3d library:appendfilebin()filesize()file_checksum_ok()calc_checksum()append_checksum()made the game load save "b" if no save "a" found.added checksum to save and load game. shows msg if checksum bad. aborts load.ran quite slow at first, doing it one byte at a time, 15 seconds? made it use 2K buffers. takes about 2 seconds. maybe 4 from disk. not bad for a 67 meg savefile.* add optimize meshes to playtest menu. remove optimize mesh from loadmeshes. march 24th:* skybox not low enough. fixed. made it unit size, centered on origin. made it draw at scale 3, centered on camera.* made sun and moon draw centered on camera, not player at y=0. skybox centered on camera and sun/moon centered on player caused parallax motion of moon when you slew the 3pv camera around.* fixed block ani 1pv* block ani 3pv* draw lit torch in hand, 3pv. added draw_lit_torch_BM(). added drawinlh(). * draw lit torch in hand, 3pv, animate the flames. set material to beacon.* change defult mapping of "sheath wpn" to the "F" key. "H" is too far from W and left shift when you're trying to sprint away and sheath your weapon to move faster.* remap input: doesnt list all control names correctly (function keys). both remap and get_vk_name used string manipulator at same tme! made get_vk_name use its own internal string.* add: reset input controls to default mapping. ## The basic game is DONE! that's right... after taking a break and evaluating skyrim, my motivation levels were back up. A final push, and as of 7pm eastern time, march 24th 2014, the basic game is done! and my original estimate of how long it would take was pretty accurate: about 2 years, working full/over time. all that's left is adding on new high end features. well, that and audio.... but the music is simple native tom-tom and flute stuff, the main theme music has already been written (for version 1.0), and the combat music is just a decent funky 4 measure drum loop remapped to a cool jungle drum kit. it would be trivial if my Alesis drum machine still worked. I plan to DL some freeware tools for that. voice acting consists of 40 samples, 20 male and 20 female, saying the 20 syllables in the caveman language. then you just play them in the correct order to say anything in the caveman language. i may just have them say random syllables. but i do have to get the infamous "bah-gah-bah" in there. In the original version, it played like a FPS when you were in combat, a settlement, or a cavern. the rest of the time it played like TheSIMs. you'd pick an action from the actions menu, and your caveperson would say "bah-gah-bah" as if saying "Ok", then go off and do the action. when they finished, they'd return to the center of the scene, and say "bah-gah-bah" again, as if saying "all done!". for the foley effects, i have the general 6000 series 50 cd sound effects library from Sound Ideas out of canada. so i'm good to go there. paid$1000 bucks for it at CGDC '96. one of the best gamedev purchases i've ever made. and about the only content i've ever paid for. well, that and pyromania 1 and 2.

and it doesn't do animations of your cave person performing an action such as picking berries, like the first version did. but it can draw a mesh or multi-mesh model in a character's hands, and it can draw every object in the game, and there;'s the built-in animation editor. so its simply a matter of making some generic animations for different actions (pick.ani, hammer.ani, etc) perhaps 1-2 dozen (watch - it'll be 50! ). then add some code to set the camera for a good animation view, set the model's animation to "hammer" or whatever, and just draw that as the action completes. right now it just draws whatever's in front of the camera, with a progress message - no animations of you doing stuff.

i've divided the remaining new features/improvements into: code, graphics, and new: actions, skills, animals, objects, etc.

remaining coding tasks have been divided into: important, less important, and "even less important". there's also an "easy" category, which i'll knock out tonight.

here's whats on the "important" list. some folks here may recognize some features they've offered suggestions about. this is a direct copy and paste from the Caveman todo list, so you can see the actual workflow document (note the time estimates on some features): * option to disable windows key - need to get online * adjustable diff levels for:healing ratehit pointscaveman encountersanimal encountersparty strength (affects number appearing) * number keys for select wpn * yield, surrender, and parlay1 DAY * add thief encounters. guy walks up, "gimme all your stuff or else!"1/4 DAY * add slaver encounters. attack to subdue. capture. model escaping, etc. - REQUIRES ADDITIONAL AI 2 DAYS * kidnappers: like thieves and bushwhackers and slavers. attack to subdue. take captive, but to ransom you back, not sell off as a slave.1 DAY - ONCE SLAVERS ARE DONE * add encounters with traders who do settlement trader's hut type trading (IE professional traders). make friendly cavemen just do "what i got on me" trading (amateur traders). * questgen1 WEEK * raiding and inter-band rivalry/conflict, and forming alliances with other bands. 3 DAYS * romance, mating, offspring.tied to relations. mate action on talk to cavemanneed very good relations + opposite sex + physical attractionneed to track who is who's mate, and who has no matemating may lead to offspring.pregnancy: food, water, sleep go down faster. fatigue goes up faster. movement rate goes down. damage or illness has chance of causing miscarriage.physical attraction: charisma, but more - phermones - genes. compatability. hmm...the 6 way street: 2way like, 2 way love, 2 way lust.3 DAYS
the questgen is big, probably a week. mating may take more than 3 days. diff levels and hot keys, probably less than a day. yield, parlay, and
surrender, a few hours. but then you have to model escaping too. All the new encounter types can be done in 2 days. raiding might only take
2 days, maybe just one, or even less, basically its just triggering an encounter. but you do have to model who's at war with who.

wait and see how it goes.

time to get back to work.

whats next?

ah yes, give the player a chance to recognize
they're lost and stop travelling cross country.
add an is_lost variable to a bandmember struct.
set it to false when they start to travel cross
country. set it to true if they get lost.
when you check for getting lost, if they're
already lost, check for them recognizing they're
lost, and stopping.

til next time...

code once, test twice!

## Progress Report: March 2014

Few progress reports, but lots of progress:

All Improved animal animations done - even the new bunny_attack animation! . The improved animations really bring the animals to life. Sometimes i'll be testing something and its like really being back in a paleolithic world.

Took some time out to finally give Skyrim a thorough evaluation. Oblivion was a major influence on the design of the original version of Caveman. I came away quite pleased with where Caveman is vis a vis Skyrim. Obviously i don't have the manpower to match them in graphics special effects or human generated content. OTOH, I found the changes between Oblivion and Skyrim to be evolutionary, not revolutionary. And it still suffers from the same design flaws as Oblivion (hard coded levels, hard coded spawn points, nothing to spend money on, rat in a maze level design, etc) plus new ones brought on by trying to add random encounters w/o thinking through the consequences (dragons, vampires, etc kill all the merchants!) and therefore not having a complete and balanced model/simulation (new merchants move in to replace those that die). Guess that's what happens when you try to add simulator type stuff to whats basically a level based shooter and don't think like a sim developer.

Spent some time (about week) playtesting and tweaking. Surprisingly little needed to be tweaked.

Implemented encounter ranges based on terrain elevation and vegetation cover.

Did final (?) improvements of caveman models.

Implemented all animations for 3rd person view:
stand
walk, run, and sprint - forward, back, left, and right.
sneak stand
sneak walk - forward, back, left, and right
climb mode stand (hang on) and walk (climb)
attack animations

graphics left to improve:
rain
falling snow
stars
prairie terrain
savanna terrain
cloud and sky brightness (both are a little dark right now)

this will bring all the graphics up to the minimum level acceptable for first release of this major new version of the game.

then there are a number of additional game play features to add, from interacting with snow, to taking rafts upstream, to high end stuff like raiding and inter-band rivalry, mating and offspring, etc. But these largely require just code, which i can kick out much faster than graphics. All the design work and rules have been worked out already, its simply a matter of typing it in. And for that i have Cscript, my secret productivity weapon.

## Progress report - Nov 2013

Progress report - Nov 2013

Its been a while since I posted any info on the Caveman project, so I thought i ought to post an update. While I haven't posted any blog entries or screenshots in a couple months, I have been very busy working on the game.

As of the last update in mid-September, a first pass had been completed at making it draw everything in the game.

Since then, most work has been on polishing the graphics, with some optimization of accelerated time mode as well.

The following was completed in the last half of September:

adding dead as well as alive bandmembers led to the "code change in 99 places!" thread, and a bit of modding of the code. In the end, its refactored, better designed, more generic, and more flexible for use with adding further features.

a simple alpha texture blending effect was used to draw snow on the ground with fixed function pipeline.

a generic ground mesh generator was created, then added to the game to create cavern floor meshes on the fly as needed. its based off the "new way" chunk terrin mesh generator, and is generic enough to be used for caverns, caves, even the outdoor terrain meshes. but the chunk system works fine, so i see no reason to refactor it to use the generic mesh generator. however, all future features will use the new generic mesh generator.

I've actually done this with a number of systems developed for the game. For instance, there are three different internal API's available for checking the conditions for beginning an action. The original API could only perform basic checks, such as some level of a single skill and some quantity of a single object. The second API expanded this some. The third and current API uses a "requirements record", a struct that contains all the info related to performing an action: skills, tools, and parts required, in what quantities, and of what quality, and what skills you get experience points in when you successfully complete the action. Since the game has 100 types of actions, and many can be triggered in multiple ways (gather wood is an option on both the jungle and woods action menus), and since the older APIs worked fine for the actions that used them, i never went back and refactored them to use the newest API. When i do need to make changes to the trigger for an action, i update it to the new API if needed. This is basically a case of "not fixing it if its not broken", because there's so much other work to be done.

I added a Zaudio library to the collection of Z libraries - a wrapper for the Xaudio2 and 3D sound APIs, and made the game use it. So the game can now play wav music and sound effects. However i still have yet to create any audio content for it. at the moment it simply plays track one off of an Offspring album as a test. can't remember the name of the album. "self esteem" and "gotta keep em separated" are on it.

Npcs now use all types of weapons and armor in the game.

The code has been modified with conditional compilation to create both a full version and a demo version of the game. the demo will be used for beta testing, and as marketing material.

The game now lets you view the model of your player.

A caveman model viewer has been added that lets you view any caveman model in the game - of which there are almost 600 now.

As an example of the level of detail in polishing graphics:
The game now draws rain outside an overhang, not inside it, when you're under an overhang. Not even Oblivion does this. try it. goto weynon priory, and walk through the "tunnel" to the stables when its raining. it rains inside the tunnel! Actually most games do this, they draw rain if outdoors, and don't if indoors, and leave it at that. It was only after i added the effect that i noticed that Oblivion doesn't do it.

A generic random map API was created. Since pretty much all of Caveman is procedurally generated, it relies heavily on "pattern maps" of various sorts. these maps specify the location and orientation of things like trees, bushes, rock outcroppings, plants, as well as things like what ground texture tile to use on a given ground quad. The heightmap for canyon floors needed improvement. it seemed a perfect time to experiment with a generic random pattern map. the map itself is a simple structure:

int randmap[100][100]

its seeded with random values from 1 through 100. the map can then be interpreted as one sees fit for any purpose. for its first use, i wrote a routine that converted an x,z location to a y altitude based on the random map. x and z were dvided by 10, then modded to get the
"randmap[x][z]" indices. an flerp was done along the north and south edges, and then between the edges, to the the exact point between the corners [x][z] and [x+1][z+1] on the randmap.

the user interface for the game was changed. it no longer displays any stats whatsoever, no health bar or anything! instead, when a stat gets low, an "idiot light" such as "low water" or "high damage" is displayed. this seems to make for a much more seamless and immersive experience.

besides the above mentioned, the following graphics were done during late September:
falling snow
cavern interiors
chasecam view in interior scenes
improvements to clouds, sky, plants, skybox, dropped objects, and lighting.

October:
* drawing swamp
* bandmember attack animations based on weapon type.
* player's model animated in 3rd person view.

* i found an interesting typo / logic error (yes, a BUG in one of MY programs!):
frame % 15 == a,
a % 15 == frame
this made NPCs numbers 15 and higher never select a new target, causing them to all run off in the same direction.

* new AI for bandmembers and npcs with missile weapons.

* hit points were re-balanced from body_wt / 10 to sqrt(body_wt). the old formula made big critters unrealistically hard to kill (like 100+ spear hits to take down a mammoth). now the hit points and damage system are in line with all available archaeological evidence as to just what it took to kill these animals.

* made accelerated time run faster. this was done by using the 2D indexes for the flatfile cave and hut databases. The game has 50,000 caves, 5000 rockshelters, and 28,000 huts. all in one big flat file database (array of structs). the first 50,000 structs are caves, the next 5000 are rockshelters, and the last 28,000 are huts. looping through 5000 rockshelters checking for encounters with their occupants isn't too bad, but doing so for 50,000 caves or 28,000 huts is a bit slow. so 2D indexes were created for caves and huts. the index is a 2d array whose indiecs are the map square coordiantes. the entry is a list of the indexes of the caves caves or huts in that map square. so encounter checks are only done vs the caves and huts in the player's map square, not all 28,000 or 50,000. this sped up the periodic encounter checks for occupants of nearby caves and huts. as a result, accelerated time runs much faster now. A fast as one game hour per real world second, while still doing full simulation of everything.

* drawing missiles (arrows, altatl darts, sling stones) in attack animations. it already draws the weapon, and draws the missiles in flight and on the ground.

* improvements to rain and falling snow effects

* improvements to rendering tall grass terrain. added a second grass texture, tweaked the textures for more realistic coloring. added functions that use the new generic randmap to do texID, scale, rotation, and offset for grass. Now the tall grass terrain is generated using a single generic random map - the same one used for canyon floor heightmaps! looks good. i'll post a screenshot.

November:

on october 30th i started on improving the animal animations. its now November 27th, and i'm still at it. The game has about 50 types of extinct mega-fauna in the game. each type of animal has 5 animations: stand, walk, run, attack, and dead. So far i've done about 40 of the 50 animals in the game. Each animal takes about half a day. The game is now up to about 110 animations total. reuse of animations between animal models has been less than hoped for. this is partly due to inconsistencies in the modeling. if a body mesh is flipped around end to end or upside down when creating the model, the rotations for the animations are backwards, resulting in some interesting moonwalk type results. This requires separate animations for critters with flipped bodies. next time, i'd just use two separate un-flipped body meshes so i could share animations. size of the animal also can make animation sharing impossible. large and small animals seem to need to move at different speeds. and the leg length of an animal has a definite effect on the speed at which a walk or run animation should play to sync properly with their forward progress across the ground. One of the big surprises is the stand animations. you would think that one generic animation of standing around doing nothing would work fine. As it turns out the stand and attack animations tend to be unique for each type of critter. Stand is where the personality of the animal comes out. so the stand animation for a hippidion proto-horse must behave like a horse, and camelops must behave like a camel, and silvatherium must behave like girrafe, and... well you get the idea... so slowly but surely i'm bringing all these extinct mega fauna back to life. testing the animations is quite interesting. You start a playtest game, punch up the animal in question, and watch it - like on animal channel! makes me feel like the crock hunter, or marty stoufer of wild america, or marlin perkins of mutual of omaha's wild kingdom. Once you've got them behaving correctly and have the walk sync'd up to the right speed, then you punch up some caveman encounters and watch the combat. this lets you check out the attack and run animations. after much back and forth of "this leg kicks out to far" and "runs still seems a bit slow", you eventually get something that starts looking and behaving like a real live animal. as i go along, some need improvements. i redid similodon populator (the biggest saber tooth ever) and homotherium (american scimitar cat) from scratch. Since taking on a saber tooth tiger was the original inspiration for the game, figured i HAD to have a better looking smilodon. so it was back to the reference photos, and the downloaded models to create a new set of limb meshes and assemble a new model. results were better than expected. A couple other models got minor adjustments to improve the head pivoting of the model for animation purposes.

i'm currently working on animal type 61, the dire wolf.

between the terrain graphics and the animal models and animations, there are times when its really starting to look like the real thing! which is much more than i could ever hope for - given that its just me, and not an army of graphics coders, modelers, and animators.

improved animations is last major thing for graphics. i'd really like to get some rayleigh in-scattering atmospherics going, but that will have to wait. there are more important features to be implemented. savanna and prairie terrains still need to be improved. looks like i'll be making my own acacia tree model from scratch, as none - even those for sale on turbosquid - looks correct. a few other minor things, and animating flames, is about it for graphics. Then its time to implement the remaining high level features such as raidung and inter-band rivalry. and then its test and tweak time, along with beta testing, and when its ready (but not until!), release!

wait, is that a speck of light i see at the end of the tunnel?

## World coordinate system based cloud particle system done

World coordinate system based cloud particle system done

well that didn't take long!

Caveman uses the following world coordinate system:

The game world map is divided up into 5x5 mile map squares. Each map square has its own d3d coordinate system. So a location in the world is speccified by map x and z, AND by a d3d x,y,z in that map square: IE mx,mz,x,y,z.

all i had to do was add an mx,mz to a cloud struct.

init them to the players mx,mz in init_cloud2

made draw_cloud3 use them instead of the player's mx,mz to calculate camera relative coordinates.

added a wrap_around_cloud function to wrap a cloud around to the other side of the cloud box when it moves outside the cloud box, or the cloud box moves beyond it.

added a movecloud function to move a cloud based on windspeed and direction from the weather engine

made sort_clouds (for alpha blending) use world cloud coordinates converted to camera relative coordinates for sorting

added a remove_last_cloud function to remove the last active cloud from the array of cloud structs. The array of cloud structs is statically allocated, as the max number of particles (currently 400) is known at compile time. each cloud struct has an "active" boolean (implemented as int, 0=false, 1=true). when a cloud is added, its "active" variable is set to 1. when its removed, its "active" variable is set to 0. only active clouds are rendered and updated.

added an update _clouds function that adds or removes clouds based on changes in cloud cover info provided by the weather engine, and then calls update_cloud for each active cloud.

added a wrap_around_clouds function that calls wrap _around_cloud on each active cloud. the "cloud box" is the area around the camera that active clouds are in. the cloud box is currently set to a bounding box radius of 2000 units around the camera, and altitudes from 500 to 700 units. since the cloud box is based on the camera's location, the camera must be set before making clouds outside the cloud box wrap around. this tripped me up for a moment. i was handling wrap around once after player/camera/cloud box movement and cloud movement had both been done. but when you changed map squares, it seemed to draw the clouds at their old position (IE 5 miles away) for one frame. doing wrap around after cloud box movement and after cloud movement didn't fix things. the reason is because the player had moved to the next map square, but render hadn't been called, yet, so the camera hadn't been moved to the next map square yet! the solution was to call wrap around once on all clouds just before drawing, at which point the camera has already been set to the new map square.

so now the clouds come and go as you move, and come and go with the winds, and don't change drawing order when you change map squares, and increase and decrease in number with changes in cloud cover. now i need to add grey and red cloud textures and make it use them when appropriate. The original version supported blue, grey, and red skies, and white, grey, and red clouds. Right now the new version only supports blue skies and white clouds.

I think a lot of why it was so quick and easy had to do with the following:

1. CScript. all the new code was done in CScript which allowed the quick coding of the simple routines required.

2. Existing functions in the game. things like normalize_location and camera_relative_coords. being able to copy paste edit x+=spd*cos(yr) etc from generic_move to update_cloud. i can never remember if its x+=sin or x+=cos. wait. just thought about it for a sec, its x+=sin(yr). but usually i'm lazy and just find the formula somewhere in the code like generic_move (moves the player any of 4 directions), move_animal (moves a non-player entity), or move_missile (moves a projectile), and copy and edit it - less typing!

3. the fact that i've been writing particle systems for games for 25 years now. yeah - i know, no fair!

CScript really is nice, i should have been using it all along. i can code new stuff and mod old stuff in a flash. and it only adds 2 seconds to the build time for 71,000+ lines of source code, and that includes the time to minimize visual studio 2012, launch CScript, click to quit when it finishes translating, maximize VS 2012 again, and hit F7 to build. I had it setup as a pre-build step, but since you edit the CScript .cs input file and not the .cpp output file generated by CScipt, VS 2012 thinks the build is up to date since the .cpp file hasn't changed (yet). this means you have to do a rebuild to trigger the CScript pre-build action, or make a change to the current .cpp file. so i went back to a shortcut on the desktop to launch CScript. i also tried it as a tool button, but you can't make it project specific to pass project specific source file names. There's probably some way to do it, but the desktop shortcut with the file name as a parameter works fine.

## Progress report - it finally draws everything in the game!

Progress report - it finally draws everything in the game!

After a long struggle with character weapons and equipment, Caveman now draws everything in the game. Some of the stuff still needs work, but at least it draws something.

I need to get caught up on posting screenshots.

making the cloud particle system use world coordinates as opposed to camera relative coordinates is next. Clouds are alpha blended. so they're sorted on range to camera. the world is divided up into chunks or "map squares" of 26400x26400 d3d units (feet), IE 5x5 miles. each map square has its own d3d coordinate system. when the player changes map squares, the world origin changes, so the camera's coordinates change to compensate. this sudden change of camera x or z by 26400 units changes the sort order of the clouds slightly (IE the difference between x,z locations 5000,0 and 5000,26399 for example). so the clouds "jump" slightly when you change map squares. the fix is to use world coordinates, IE map square x,z plus d3d x,y,z in the map square. when the player leaves a cloud far behind, its regenerated on the leading face of the could cube area that surrounds the camera.

the general idea of the cloud particle system is you have a cube shaped area that surrounds the camera (a "cloud box") that's full of cloud particles. info from the weather engine is used to move the particles, and to determine the number active. when a particle moves out of the "cloud box", a new position is randomly generated for it on the opposite face of the cloud box from the face it exited through. the cloud box moves with the camera. when the cloud box moves so a cloud exits the box, again, the new position for the cloud is randomly generated on the opposite face. by "on the opposite face, i mean in that direction and at that range from the camera - IE somewhere on that face of the cloud box.

right now the could system doesn't use world coordinates, and its not hooked up to the weather engine. it just draws 100% cloud cover and stationary clouds (IE cloudcover 1.0f, windspeed 0.0f, winddir 0.0f weather settings) for testing the alpha blend effect. but the api's already exist to hook the two together.

## Caveman v3.0 general desciption

[color=rgb(40,40,40)][font=arial]CAVEMAN 3.0 general description.[/font][/color]
[color=rgb(40,40,40)][font=arial]Someone suggested i post a description of CAVEMAN as a reference link in threads about the game.[/font][/color]

[color=rgb(40,40,40)][font=arial]CAVEMAN is a fully immersive 3d Paleo-World simulator. Its a persistent modifiable open world RPG / person sim, with a fps / 3ps interface.[/font][/color]

[color=rgb(40,40,40)][font=arial]so its sort of a cross of a fps like Oblivion, an RPG like table top D&D or Traveller, and a person sim like The SIMs.[/font][/color]

[color=rgb(40,40,40)][font=arial]you can do all the normal rpg stuff, plus you can select almost anything in the environment and interact with it like in The SIMs.[/font][/color]

[color=rgb(40,40,40)][font=arial]The setting is paleolithic, about 200,000 to 10,000 years ago. no techno. no magic.[/font][/color]

[color=rgb(40,40,40)][font=arial]the player can control a band of up to 10 cavemen (like a household in The SIMs).[/font][/color]

[color=rgb(40,40,40)][font=arial]Band members have core stats like strength, intelligence, etc. - the usual RPG stuff.[/font][/color]

[color=rgb(40,40,40)][font=arial]Band members also have variable stats as seen in The SIMs, like food, water, hygiene, and mood.[/font][/color]

[color=rgb(40,40,40)][font=arial]46 skills and experience in each. You can research, teach, and learn skills, as well as acquire then through use.[/font][/color]

[color=rgb(40,40,40)][font=arial]no classes.[/font][/color]

[color=rgb(40,40,40)][font=arial]a 2500x2500 mile randomly generated, persistent, modifiable world. The "ground mesh" for the world is procedurally generated in chunks on the fly as needed from data structures containing the "world map" (right down to the last rock, plant, and clump of grass). The entire world ground mesh is [/font][/color]87.12 TRILLION triangles[color=rgb(40,40,40)][font=arial].[/font][/color]

[color=rgb(40,40,40)][font=arial]Over 200 types of objects you can make or find.[/font][/color]

[color=rgb(40,40,40)][font=arial]62 types of weapons.[/font][/color]

[color=rgb(40,40,40)][font=arial]Over 50 types of extinct Mega-fauna to hunt or be hunted by.[/font][/color]

[color=rgb(40,40,40)][font=arial]thousands of possible actions, from filling water skins, to repairing a bow.[/font][/color]

[color=rgb(40,40,40)][font=arial]exploration, resource gathering, crafting, and trade.[/font][/color]

[color=rgb(40,40,40)][font=arial]In depth modeling and simulation of lots of stuff, from windage effects on arrows to death by background radiation (IE old age).[/font][/color]

[color=rgb(40,40,40)][font=arial]The player starts with one band member, but can get NPCs to join their band.[/font][/color]

[color=rgb(40,40,40)][font=arial]The objective is for your band to become as powerful as possible and last as long as possible.[/font][/color]

[color=rgb(40,40,40)][font=arial]The game ends if all your band members die. [/font][/color]