• entries
    44
  • comments
    44
  • views
    58280

About this blog

About the game Caveman

Entries in this blog

Norman Barrows
The building of Caveman - Part 5 - General code organization


This is the general code organization used in Caveman:


void main:
----------------
initprog
runprog
endprog





initprog
------------------
init z3d game library - creates window, goes into 3d mode, creates fonts, inits audio, random number generator, timers, etc.
rockland animation - show company logo animation
load all assests - show loading screen. load: meshes, textures, models, animations, wavs, etc.
show title screen



runprog
-------------------
show main menu:
continue - load last saved game, rungame.
tutorial - init tutorial game, rungame.
new game - init new game, rungame.
load game - load saved game, rungame.
help - show help
tools - show modding tools menu
quit - quit caveman


endprog
-------------------------
unload all assets
shutdown d3d, audio, etc




Rungame is the main game loop, the real guts of the game. The game uses a fixed time step. The framerate is limited
to 15 FPS. Testing has shown this is the slowest a game can run and still be sufficiently responsive. The game has
accelerated time, so render is called one or fewer times per turn (update frame), depending on game speed. Caveman is
a hybrid game that combines FPS/RPG play with with the ability to interact with the environment, as seen in The SIMs.
The are hundreds of possible actions, from drinking water to making a stone knife. When the player is perfoming an
action, they can't move or fight, and must wait for the action to complete. Action specific handler code is called
each turn (update frame). When they are not performing an action, they can run around like in any normal FPS/RPG.

rungame
--------------------------while !quit { if ((turn_counter % turns_per_render)==0) drawscreen // render if (player_doing_action) do_action else process_input increment_game_clock run_simulation // update limit_framerate }
do_action
-----------------------------
runs the action handler code for the current action.
action handler code typically increments a counter, and after some limit is reached, performs a success check,
updates the simuation as needed, and ends the action. While performing an action, input is limited to
changing game speed and stopping the action.


An example action handler: drink water. this increases the bandmembers water by one every 10 turns until it hits
100, at which point it stops the action:

drink water
------------------------------------------------inc bandmember[a].action_counter[DRINK_WATER]if bandmember[a].action_counter[DRINK_WATER] < 10 returnbandmember[a].action_counter[DRINK_WATER]=0inc bandmember[a].waterif bandmember[a].water>=100 { bandmember[a].water=100 bandmember[a].current_action=DO_NOTHING }


process_input
------------------------------------
processes mouse and keyboard input. input controls can be remapped. raw inputs are mapped to input controls
such as IN_LEFT, or IN_ATTACK. process_input polls the input controls at 15 FPS, and always polls at least
once per render. movement inputs are translated into a move direction of forward, back, left, right, one of
the four diagonal directions, or none. code is then called to move the player in that direction, and play the
correct movement animation. About the only unusual thing about the code is the fact that movement must be
processed before jump, for movement velocties at takeoff to take effect while airborne. Caveman uses realistic
gravity and physics modeling for missiles and falling creatures (including jumping). So just like the real
world, once your feet leave the ground, you can't change your velocity. its all about your initial launch
velocities. Movement must be processed before jump to set those velocities.







run_simulation
-----------------------------------------
this is the main "update" routine. updates are done on an as needed basis. so things that get updated every
frame are updated in do_global_frame2, and things that only need to be updated once per second are updated
in do_global_second2, and so on for global minute, hour, day, and year.void run_simulation2() // the "model stuff" engine{do_global_frame2();if (frame==0) { do_global_second2(); if (second==0) { do_global_minute2(); if (minute==0) { do_global_hour2(); if (hour==0) { do_global_day2(); if (day==0) { do_global_year(); } } } } }}



do_global_frame2
-------------------------------------------------------------------------
this is the main update routine called every frame. it updates: bandmembers (PCs), missiles, animals (NPCs), rafts,
and clouds. Note that attacks are resolved one second after they are initiated, and a hit is only scored if the
weapon hits someone at that point in time. Also note that surprise is modeled in the form of "freezing" for a few
seconds before an entity can move or attack. move_rafts2 models raft movement (duh!) but also moves bandmembers,
NPCs, and dropped objects which are aboard the raft. So you can actually walk around and place object on a raft
while its in motion. model_falling2 handles the physics modeling for falling entities. update_clouds updates the
cloud particle system based on variables from the weather engine.
void do_global_frame2(){int a;BMupdate_all();model_missiles(); // model missile movementmove_animals(); // move animalsif (last_active_animal >= 0) // model animal attacks { for (a=0; a <= last_active_animal; a++) { if (!animal[a].active) continue; if (!animal[a].alive) continue; if (!animal[a].attacking) continue; animal[a].attack_counter++; if (animal[a].attack_counter>=30) { animal[a].attacking=0; animal[a].xr=0.0f; animal[a].attack_counter=0; continue; } if (animal[a].attack_counter==15) new_resolve_animal_attack(a); } }if (last_active_animal >= 0) // model animal suprise { for (a=0; a <= last_active_animal; a++) { if (!animal[a].active) continue; if (!animal[a].alive) continue; if (!animal[a].suprised) continue; animal[a].suprise_counter++; if (animal[a].suprise_counter>60) animal[a].suprised=0; } }move_rafts2();model_falling2();update_clouds();}
do_global_second, minute, day, and year are similar, modeling everything from animals entangled in nets or
bolas getting free, to background radiation (old age).


And that's the basic code structure of the game. pretty straight forward, a fixed time step game loop, with framerate
limiter. The only unusual things are: FPS/RPG mode or SIMs style do action mode, and the render based on
accelerated time.

Part 6:
https://www.gamedev.net/blog/1730/entry-2260310-the-building-of-caveman-part-6-data-structures/

Part 4:
https://www.gamedev.net/blog/1730/entry-2259583-the-building-of-caveman-part-4-the-z-game-library/
Norman Barrows
[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]
Norman Barrows
Caveman 3.0 Beta 12 released!

PLAY NOW!
http://rocklandsoftware.net/beta.php

Game info:
http://rocklandsoftware.net/Caveman.php


New for beta 12:
---------------------------------------------
* refactored and improved AI
* give orders to party members
* sound effects
* music
* animations for actions

details:
* following band members now keep up during cross country movement.
* band member AI uses best weapon
* band member AI leaves temp shelter on hostile encounter
* band member AI: stops action if animals nearby. animal must now be within 50, not 100. warriors, companions, tamed, subdued, captured, and non attack_AI animals are now excluded.
* game now checks for encounters once per party, not once per BM. doesn't check encounters for BMs who are within 300 of a BM who has already had their encounters checked.
* fixed: don't let 2 bm's butcher same animal!
* band member AI: attack orders: doesn't attack wounded fleeing thief? cant catch - target too fast?
fixed: was comparing target run speed vs BM walk speed for "skip if target is to fast to catch"
* new AI and orders menu design
* new bandmember AI done
* new orders menu done
* compiles with no warnings with all warnings turned on. fixed a half dozen non-explicit conversions, made them explicit.
* compiles with no warnings in static code analysis. fixed a few potential range check errors, and a couple of possibly uninitialized variables.
* made new band member AI use sprint speed
* made new band member AI play correct animations
* animal and avian AI done
* model animal fatigue
* model animal (flunkey) sneak detection
* set "animal taking fire variables" in check_missile_collision code
* avian version of do_orders
* new avian AI
* load and save animal[a].diving
* collision maps
* ambient sfx
* water sfx
* fire sfx
* BM atttack sfx
* play action animations w/ ani camera view
* finished animal attack sfx
* npc attack sfx
* bm take non-missile hit sfx
* npc take non-missile hit sfx
* code for animal take non-missile hit sfx
* takehit sfx for all animals
* random grunts - caveman ambient audio
* missile hitting tgt sfx
* code to play action sfx
* assign sfx's to all actions
* assign make/repair sfx's to all object types
* get/find sfx for all object types
* sfx when learn skills that use male/female voice (singing and talking type skills)
* ocean sfx when near ocean
* action anis
* stop all wavs when quit game.
* don't let player tab to dead BM
* music
* all audio working
* no random sfx at high game speeds - runs out of voices
* destroy_finished voices added to run_song, stop_all_wavs, and play_ambient_audio
* music starts at title screen now - not main menu
* when possible, uses sfx/wav # != -1, not Zvoice_is_playing to determine if a wav is playing
* use shift select for give bm item
* band member menu: show bm name and relations
* abandon current hut and take over this one: i suspect they will lose all their stuff at the old hut!
when hut is abandoned, instead of asking player if they want to abandon their old hut and take this one over,
create an abandoned hut world object that weathers away over time.
player can take it over at any time.
abandoned hut actions: takeover, inspect, demolish.
added abandoned_hut object, and inspect and demolish actions for abandoned_huts
* remove non-hostiles over time when gamespeed > 128x
* increased volume of smallherd_takehit.wav
* fixed defend ai: now only attacks if tgt is within 50.
* tutor: automatically stops cross country movement when the player first finds water, food, and rocks.
* audio: fixed: didnt check for voice ptr=0 in voice is playing
* doesn't switch to action ani fast enough? was calling startani with params reversed!
* fixed: cave hyena attak sfx is lame
Norman Barrows
An example of a big change to Caveman

I've been playtesting a lot recently.
Drawing objects in an avatar's hands in animations
is the next thing on the todo list - and that's just
eye candy. I'm into gameplay, not eye candy.
So I've been playtesting my long term playtest game,
making note of fixes to be made. I've gotten to the
point where I have 10 bandmembers in my band!
Occasionally I'll stop and make a change necessary
to continue testing. But that is becoming less
and less frequent. I can test for an entire day
with no changes required to continue testing.
That's a sure sign that the game is getting closer
to completion, when everything is working correctly
and no major issues are encountered while testing
for hours or days on end.

I just finished a change that was really required
for futher testing. Permanent shelters have been
replaced by a new type of object, a PLAYERHUT.
Before the change, each bandmember had to create
or takeover their own hut, and they were limited
to one each. Now, each bandmember can create
or takeover as many huts as they wish, and huts
are owned by the band, not individual bandmembers.
So one bandmember with lots of construction skills
can build huts for all the bandmembers.

A description of the changes involved:

#declare object type
--------------------
defines an ID number for this type of object.

the game tracks items in the world using a
"objrec2", which is an instance of 1 or more
items of a given type and quality at a given location.
lists of objrec2's are used for containers, PC and
NPC inventories, and the world objects list (dropped
inventory items and items built by the player -
such as huts! ).
The game uses a relational database design, with
objrec2's pointing to object type instances in the
object types database, via a object type ID number.
object type instances contain info like name, weight,
and price which are common to all objects of a given
type.

init_object_types_database
--------------------------
inits the object type's entry in the object types
database. IE sets name, weight, price, etc.
not much here, i set the name and radius but the
code uses neither! :O



PLAYERHUT methods:
------------------
build
inspect
repair
demolish
in_way_of_drawing // boolean. dont draw plants etc in huts!
in_way_of_moving // boolean. collision check
add_to_collision_map
// adjusts 3pv camera location to hut interior
get_3pv_camera_coordinates
first_BM_nearby
raid // conducts hostile caveman raid on a player hut


should get_3pv_camera_coordinates be a camera method or a
playerhut method?
it uses both...
continuing along those lines...
should in_way_of_drawing be a render method?
should in_way_of_moving be a physics method?
should add_to_collision_map be a collision map method?
should first_BM_nearby be a bandmember method?

more and more its seems that for loose coupling and tight
cohesion, code ought to be divied up into two types:
1. low level classes that know only about themselves,
and
2. controling code that uses low level classes.

then the controling code would do something like:
loc=bandmember.get_location
loc2=calculate 3pv camera location from loc
playerhut.adjust_3pv_cam_location(&loc2)
camera.set(loc2)
bandmember, playerhut, and camera only know about
themsleves. only locations are passed between them and
the controling code.







world objects list methods:
---------------------------
// checks if a world object is in any player hut
worldobj_in_playerhut
// checks if a bandmember is in any player hut
BM_in_playerhut
remove_stuff_nearby_playerhut



render methods:
---------------
draw_world_objects
draw_local_map
draw_world_map


process_input methods:
----------------------
selected_playerhut // boolean
playerhut_menu // playerhut actions
takeover_abandonded_hut


update methods:
---------------
remove_distant_dropped_objects // dont remove stuff near huts!
model_playerhut_raids // calls playerhut.raid if a raid occurs
model_playerhut_weathering


other methods:
--------------
// boolean. checks if bandmember is near a player owned cave, rockshelter, or hut
BM_near_shelter
// boolean. checks if player owns a cave, rockshelter, or hut
owns_shelter




The actual changes were pretty straightforward.

permanent shelters used:
bandmember.has_perm_shelter
bandmember.perm_shel_quality
bandmember.shel_mx
bandmember.shel_mz
bandmember.shel_x
bandmember.shel_z

and player huts use:
worldobj.active
worldobj.qual
worldobj.mx
worldobj.mz
worldobj.x
worldobj.z

all the code already existed, it just needed to be changed to use
PLAYERHUT world objects instead of a bandmember's permanent shelter.

One prime motivation for this change was the fact that caves,
rockshelters, and NPC huts you can take over now occur at random
locations in a map square (a square 5 miles across). They used to
be at most one of each per map square, and always in the same place.
And if there was water in the map square it was always nearby all
of them - IE everything was near the center of the map square.
Now its much rarer for a cave or hut to be near water and all
rockshelters are more than a mile from the closest water. So
building a hut is the best way to get a shelter close to water,
which is the most frequently required required resource in the
game. And it takes a lot of skills to build a hut. The research
tree is incredibly long and complex. So requiring each bandmember
to go through this to be able to build a hut when their fellow
bandmember(s) already have the skills to do so didn't make sense.
Not sufficiently realistic, needed to be improved. Thus the change.

And now...

I'm off to build huts for all my bandmembers! smile.png

You should see what its like trying to cram all ten of them in one
hut so their mood doesn't go down from being out in the rain! .
Norman Barrows

The new PC has arrived (i7-6700K, GTX1080), and I'm starting on the final graphics for the game.

Better grass plants were one of the first things. The placeholder graphics were ultra-low-poly, just 3 or 4 quads. I could only draw them every 5 feet or so, any closer together was too many instances. They were scaled very wide and flat to cover the gaps. it looked ok en masse, but individual plants weren't that great.

So after watching Youtube tutorials, i made some better plant models. I was testing them out, but noticed a frame rate hit. 2500 instances was ok, but a bit of a performance hit. 10,000 was a big performance hit.

So i did some experimenting. i would track the number actually drawn, and the number of polys in the mesh being used, and the FPS, and the scale. at first it seemed the number of draw calls was having the biggest effect, followed by the number of tris in the mesh used, with mesh scale (big tri rasteriization) practically no effect (scale up the grass in your game to 20-30 feet tall - it looks wild!). but on closer inspection, i was drawing about the same number of quads with 10000 one quad meshes vs 2500 3 quad meshes, but 10000 was half as fast. turned out it was the figuring out of which of the 10,000 to draw that was the performance hit.

So then it was time for some test code. The optimal way to do it would be to pre-calc the lsit of plants to draw, along with their world mats. set the texture, material, mesh, clamp, cull, tex scale, etc just once, then for each plant in the list, set world mat, then call D.I.P.

I tried it with 2500 plants. a 100x100 foot area with one plant every 2 feet. worked like a charm. no change in framerate. still 60 FPS. then i tried 10000 plants (200x200 foot area, one plant every 2 feet). worked like a charm. no change in framerate.

screenshots:

gallery_197293_593_962883.jpg

the total meshes drawn is in addition to the 10000 grass plant meshes. those are the ground, tress, berry bushes, the huts, the teepee, the fire, people, etc.

gallery_197293_593_871115.jpg

this shows a closeup of the grass. still needs work, but its getting better.

and here's the test code: /* optimal: pre-calc all world mats set alphatest, cull, clamp, material, and tex scaling once. set each tex once. for each tex, set each mesh once. for each mesh, set world mat, call DIP */ #define max_grass_list 10000D3DXMATRIX grass_list[max_grass_list]; int num_grass_list;void init_savanna_grass_list(){ int x1,z1; float x,y,z,sx,sy,sz,ry,jitter,scale; ZeroMemory(grass_list,sizeof(D3DXMATRIX)*max_grass_list); num_grass_list=0; for (x1=0; x1<100; x1++) { for (z1=0; z1<100; z1++) { x=26200.0f+(float)x1*2.0f; z=13100.0f+(float)z1*2.0f; jitter=grass_offset((int)x,(int)z); jitter/=2.0f; x+=jitter; z+=jitter; y=heightmap(cm[cm0].mx,cm[cm0].mz,x,z); scale=(float)grass_scale((int)x,(int)z); sx=scale*0.05f; sy=scale*0.03f; sz=scale*0.05f; ry=grass_rotation((int)x,(int)z); Mstart(); Mscale(sx,sy,sz);// MrotateRADS(0,rx); MrotateRADS(1,ry);// MrotateRADS(2,rz); Mmove(x,y,z); grass_list[num_grass_list]=Mmat; num_grass_list++; } } }void test_draw_savanna_grass(){int a;HRESULT result;trace[0]=0;Zsettex(454); // 6=oceanZsetmesh(4);Zalphatest(1);Zcull(1);Zclamp(1); Zsetmaterial(7);Ztexture_scaling(0);for (a=0; aSetTransform(D3DTS_WORLD,&grass_list[a]); result=Zd3d_device_ptr->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,Znum_verts,0,Znum_primitives); trace[0]++; if (result != D3D_OK) { Zmsg2("test draw savanna grass error"); exit(1); } }}
so it would seem that lots of drawcalls is not necessarily a bottleneck. perhaps even less of a bottleneck than high poly meshes. i tested plant meshes with as few as two triangles, and as many as 64 triangles. as is often the case, its visible surface determination that's the bottleneck here. In such cases, optimization in the form of DOD seems to be the best approach.


EDIT:

I turned off the test code to draw savanna grass, and turned generate_savanna_grass back on. I kicked it up from one plant every 3 feet to 1 plant every 2 feet (from 10,000 to 22,500 plants per 300x300 foot chunk). This required an increase in the number of max_meshes in a terrain chunk (from 20,000 meshes to 25,000 meshes). but with a chunk cache of 90 chunks, that ran out of memory. So i knocked the cache size back down to its original 30 chunk size.

i'm now making 36,000+ draw calls per frame at 60 FPS - clip range in this shot is set to 400 feet for everything:

gallery_197293_593_1236413.jpg

Since the data structure for visible surface determination is the key to all this, i'll provide a few details....

the entire graphics engine is build around a struct called a Zdrawinfo struct. it contains all the basic parameters for a draw call, such as mesh ID, texture ID, material ID, and flags like cull, clamp, alphatest, etc.

When a terrain chunk is generated, data from the world map and plant maps determine the terrain type and placement of trees etc. A terrain chunk is a list of Zdrawinfo structs - all the meshes in the chunk. it also has an index, which lists the structs in texture, mesh order. When a mesh is added to the list, an in-order insertion is done to the index. so the chunk contains the list of Zdrawinfo structs, and an index that consists of a list of textures, and for each texture, a list of meshes, and for each mesh, a list of instances in the Zdrawinfo list that use that texture and mesh combo. The index is implemented using ints for storage, and stores texture IDs, mesh IDs, and Zdrawinfo list indices . When rendering, the index is used to draw the meshes in texture, mesh order - to minimize state changes. The graphics engine includes state managers for all states such as cull clamp, alpha test, etc. - so so any redundant changes occurring there while rendering the instances of a texture.mesh combo will be automatically filtered out. Chunks are generated on-demand in the foreground if necessary, as well as being generated in the background using a multi-pass look ahead system to generate chunks around the player before they move into visible range. Generating 22,500 plants vs 10,000 in a single background pass is slightly noticeable. I'll probably need to split that up into two passes. Depending on the type of terrain in a chunk, a chunk can require up to 6 or 8 passes to generate in the background. background chunk generation runs at 15Hz. The game now features a user defined variable frame rate limiter that scales update to the desired framerate. Vsync is still on to avoid tearing, but desired FPS values of 1 through 1000.are supported by the code - if you have the hardware to do it.

NOTE: Apologies for the somewhat dark images. these screenshots were taken at 6:30 AM game time under natural lighting conditions.

Norman Barrows
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...
Norman Barrows
Caveman v3.0 Beta 19 released!


Play now!
http://rocklandsoftware.net/beta.php

Numerous changes in Beta 19:

* added export band member
* added import band member
* added de-activate band member
* make pigment rock object smaller.
* draws obj in hand for find pigment rock action.
* confirmed game won't run on XP.
* added obj in hand for make/find objects #70 pigments thru #173 blanket (103 objects - some need new anis though). added dinfo and fix as needed. made draw_dropped_object use dinfo where appropriate.
* added: stone drill required to make stone top armor.
* completed first pass at assigning obj in hand for make or find anis for all 237 object types. but some still need new graphics and / or anis. so most make, find, and repair animations draw object in right hand now, say 400-500 animations or so.
* reduced size of clay object
* make, repair, demolish type animations drawn closer to ground.
* increased NPC base chance to hit from 50% to 70%.
* increased BM hand attack base chance to hit from 60% to 70%.
* increased BM missile attack base chance to hit from 50% to 70%.
* moved make ani back down to -1.5
* made selected_dropped_object the first check in select().
* turned off colision avoidance in rocks. terrains is so thick they appear to just cycle between collision avoidance and collision recovery.
* select: checks for shelter before bedding.
* collision recovery: cut recovery time in half, since they now move at sprint speed (2x run speed)
* BM attack AI: explicitly calcs rng to tgt for start of attack. rng may have not been preset in cases such as "attack orders tgt", which overrides the tgt set by set_tgt. set_tgt pre-calcs rng and rh to tgt when it set the tgt.
* BM AI: no badguys nearby: priorities changed to:
1. do action
2. collision recovery
3. do orders
4. recover fatigue
5. stand
* BM collision recovery: cut recovery time in half, since they now move at sprint speed (2x run speed)
* maintain dist ai: added is_maintaining _distance AI state flag to animalrec.
AI now flees at 25 and stops fleeing at 50, instead of starting and stopping at 20.
* added BM AI on/off for CM0 via backslash key w/ AI display
* BM AI: draws wpn if attacking
* BM AI: reduced start atk rng
* sleep ani drawn lower to ground
* made sleep take a little longer
* increased rad for "inside perm shelter" from 5 to 10 feet
* daydream, watch clouds, stargaze: mood now goes up one every 5 minutes not 6.
* improved bigdice routine
* AI backs up at half speed
* BM AI start attack range for missile wpns set to 50.
* turned off collision avoiadance in woods - too dense
* collision avoidance rng reduced fro 15 to 10 ft
* playtesting
* flint spear: reduced cordage required from 3 to 2
* doubled value of hides and all objects made from hides
* done - made int affect building and fixing hut
* done - made int affect learn action: time, chance, and xp earned.
* done - fill waterskins takes too long
* done - draw all bm's on local map
* done - remove dead / butchered / sacrificed anilas after a while
* done - kick bm out of band
* done: " you learned something new about " msg
* done: show bm name for a few secs when tab to next bm
* done: changed "do" and ".do" keywords in cscript to "d" and ".d". removed all c++ code blocks from source code. all code is now cscript or c++ that does not conflict with cscipt keywords. no c++ code pass thru blocks required! no "cpp" and ".cpp" everyhwere in the code! recompiled all source code with new version of cscript.
* done: made perm shelters a world object
* done: repair: parts reqd: 1/2 round down, not up.
* done: repair: quality is now avg of old and new.
* done - too easy to find cool rocks
* done - adj party str - too many badguys?
* done - companion ai stop when within 20
* done - increase base chance to make lean-to
* done - made int have greater effect on time and chance to learn stuff
* done: increase value of hides and stuff made with hides
* done: make flint tipped spear: only reqires two cordage.
* done: objects ropped in aved get placed outside caves.
* done: made int affect qual of tirm repaired
* dont let them pickup player huts - and abandoned huts - and landmarks
* adjust hut collision checks
* separate key for pickup dropped object. - z?
* bmsg "you pass out from lack of sleep"
* add "quiting caveman" screen at end of prog
* storepit full msg added, objects no longer lost when pit is full.
* precip increases water table by twice as much. no precip reduces water table by half as much. water table goes to baseline twice as fast over time. had global warming issues.
* automap_small_stuff radius increased to 300 feet
* fixed: automap_small_stuff does huts now.
* added next idle band member hotkey "N"
* daydream etc increases mood faster
* bmsg you arrive at your dest
* quiting caveman screen
* show all parts / skils for action if you dont have something
* joke and story actions: increased chance of relations improvement, increased mood boost.
* doubled find time for flint and cool rocks
* added initializing blank game msg
* increased base chance to make temp shelter. made int affect chance. improved how chance is calculated.
* increased chance to make storepit
* reduced caveman base number appearing.
* reduced effect of party strength on cavean number appearing
* party strength based on those within 300 feet, not on those in same map sqaure.
* increased drawing radius of bedding and storepits
* fixed: party_strength: using a continue statment in the while loop skipped the call to next_active_BM at the end of the loop. hazards of using a "findfirst/findnext while loop" instead of a "0 to max for loop". bloody generic iterators!
* make cordage, make arrow actions: now continue until you run out of parts.
* show next BM name in UL corner of screen for a moment when tab to next BM.
* remove butchered / sacrificed animals after some period of time.
* increased no draw rng for huts and storepits.
* fixed: common ai: tgt is stronger: was using BMs hp adjusted for diff lvl, not base hp for a type 2 animal (homo sapien). predators would close, then flee during common fight or flight.
* fixed: subdued and captured animals shouldn't be able to move.
* turned off atk to subdue. doesnt make sense for domesticating dire wolves, and you can't subdue and capture cavemen, and you shouldnt really be able to domesticate anything else, so...
* dire wolf hp reduced to less than humans so they dont atk people.
* need to implement new way to domesticate dire wolf. dire wolf goes for dropped meat. drop enough they follow you. drop more they allow you to approach. give meat action. give enough meat, they become pet. added new dire wolf AI: if dropped meat nearby, they goto dropped meat and eat it. eat enough, they start following the closest BM at that time. eat more, that bm can approach and select and get dire wolf menu (give meat, cancel). give enough eat, they become state=TAMED.
* dire wolf - they dont move to the meat - exhausted? called run (spd based on rng to tgt) instead of run maxspd
* fixed: predators ignore stronger animals. sets pred tgt (ignore equal or stronger) only when hunting, and sets wild tgt (dont ignore any) the rest of the time.
* fatigued animals now rest until fully rested, not 2% rested
* wolf: moveto owner: runs if rng > 100
* wolves with relations > 1000 are not removed when distant
* player can now accel tieme faster than 128x when only predators weaker than humans are nearby
* added message when tame wolf
* added "enter name for new pet..." when tame wolf
* fixed: other wolves attack your wolf when you tame it. friendly wolves no longer count as leader for flock behavior. other wolves now wander off.
* fixed: wounded tame animals flee forever. made AI flee from closest threat, not current target (pet owner if pet is far from owner). added closest threat function based on animal type (wild animals and hostile cavemen, -or- pets, warriors, companions, friendly cavemen, and bandmembers).
* predators now only target weaker foes, not equal or weaker.
* wild leaders for flock behavoir now excludes tamed animals and friendly wolves.
* fixed: drink from leaves: says its snowing when its raining! used 40 degrees instead of SNOW_TEMP. searched the entire code. this was the only place SNOW_TEMP wasn't used when it should be.
* fixed: pick fruit crashes game. tool_and_part_quality: calculating avg quality of tools and parts used: did divide by zero if numtools and numparts was zero. now returns quality of 100 of numtools and numparts is zero. did same fix to RR_tool_and_part_quality. no other occurances of similar code "/ sum count" in the game. shift select blows up if list full, no range check? - same bug.
* fixed: pick fruit action - game crashes. tool_and_part_quality: calculate avg tool and part quality: divide by zero if numparts and numtools = 0. now returns quality 100 if numprts and numtools = 0. did same fix to RR_tool_and_part_quality. searched entire code for: "/ sum" to find bugs similar to: "/ sum count". none found.
* fixed: full storpit - get stuff - scroll way down crahses? select_object and shift_select_object: list was 20 long, now is 40 long, scroll limit was still max-20, not max-40. no similar bugs found.
* animals list full? added error messages everywhere the game adds animals.
* cool rocks still too easy to find. doubled time required. cut chance in half. works out to about 4x as hard.
* fixed: demolish wood shelter doesnt take long enough. demolish_shelter action used buildtime(world_object_index), not buildtime(world_object_index.shelter_type) oops! .
* fixed: demolish leanto doesnt take long enough: fix to demolish_shelter action fixed this too!
* base chance to make bedding too low? increased from 50% to 70%
* bow wears out too quickly? cut avg rate of wear by factor of 10.
* add storepit - doesnt rest chunks and collision maps? the low level funtion now does it for all calls to add storpit.
* fixed: demolish bedding in shelter demolishes the bedding. was demolishing sheletr_index, not sheleter_index.bedding_index oops! .
* fixed: shelter weathers away while bm inside asleep, or inside in general. added msg that your temp shelter weathered away.
* fixed: ingame menu: increase width of hotspots
* fixed: ingame menu: video and gameplay hotspots overlap
* fixed: ingame menu: only play klik when the click on an option.
* fixed: dont let them move x-country from inside temp shelter. did "up a tree" too! now can only move x-country when OUTSIDE or ONRAFT
* fixed: npcs: all interests should be unique
* show msg when complete search dead caveman action, then show the take item screen.
* search dead caveman: if they dont have anything, just show a msg instead of the take item screen.
* fixed: daydream etc should reduce fatigue. energy wasn't set to 1 for daydream, stargaze, and watch clouds actions. energy=1 means they recharge fatigue while doing that action.
* fill waterskinrain doesnt take long enough - increased time by factor of 10.
* done: to make / fix (skills list) msg: dont say make / fix. its used for stuff like learn too!
* fixed: collision recovery moves before it finishes turning? now it doesnt move until abs(rh) < ~11 degrees, not <45 degreees.
* what happens when run out of ani players? turned on error msg in z3d library
* fixed: falling rain should not wake up bms inside a hut. BMs in player huts and rock shelters are not woken up by precip.
* fixed: move following bm's moves any following even if not nearby or following someone else. only move nearby who are following the BM in question.
* increase size of collision map cache. increased from 20 to 40.
* done: make mouse wheel zoom camera in and out faster. did keyboard controls too (numpad plus and minus by default).
* done: 3pv cam vs hut interior - switch to 1pv temporarily? uses 1pv when player is inside hut.
* fixed: glypto moves too fast. cut speed in half.
* big cats get stuck in woods
. big animal encounter spacing vs rocks and other dense terrain
. big animal encounter rng too close
. elasmo vs woods
. imp mammoth encounters too close to player.
. imp mammoths start too close togetehr. flip betw collision avoiddance and recovery.
. palorchestes gets stuck in woods
increased spacing. increased encounter range based on size of group. now near edge of group, not center of group, is at encounter range. fixed something in way of animal - it didnt take radius into account - thus the animals stuck in rocks etc. now it checks center, and the 4 bbox corners for something in way of an animal when doing initial placement of animals encountered.
* fixed: game crashes when you try to fix something that can't be fixed (wood grindstone, 1 hand hammer, etc). now it gives you a message saying that type of object can't be repaiered.
* fixed: follower joins band: rain sfx stops. player stuck in collision with new BM.
action sfx init-ed to 0 not -1. didn't adjust bandmember location. adj bm loc didnt handle radius.
stuck in collsion with new bm: rounding error: animal_in_way_of_bm used float rng, bm_in_way_of_bm used ints. now both use floats.
* fixed: move followers, moves those with orders to the contrary suchas wait here goto here, etc. followers with goto orders, or orders to follow someone other than the moving BM, dont get moved.
* attack thief - all neutrals become hostile? only if you attack before the dialog shows.
* yield: init NPC_type so yield works? test yield. make sure it works. it may not use npc_type anymore. yield works. npc type is set already. make thief_dialog set thief to NPC_KILLER if they
become a HOSTILE.
* cave hyena didn't attack? increased hp of some predators so their AI will attack humans
* orders: atk: doesn't work when no tgt? or at all? need to test it some. if no orders tgt, uses current tgt, if none, doesnt atk. tested. woking fine.
* fixed: order pet to wait here doesnt work. b2_issue_animal_orders told animal i to goto bandmember i's location, not animal i's location. a copy-paste-edit error, introduced when converting the code from cm[] to animal[]. but follower AI still needs help. they follow owner before following orders!
* follower ai needs help - make it like bm ai. changed follower ai:

old priorities:
do common AI
move2owner if > 100
if tgt nearby do orders or atk
listen to story etc
moveto owner if > 20
stand

new priorities:
do common AI
do orders (if has orders)
atk nearby tgt (if has one)
listen to story etc
set move2owner_flag
move2owner (if flag set)
stand

* fixed: game doesn't model spoilage of food in storepits
* already done: teach doesn't take as long as learn? already fixed: learn was called once per game minute, and teach was called once per frame (update or turn) - IE 15x per game second.
* show skills: dont show last 3 undefined skills. dont show mapmaking. is bonelore used? mapmaking? re-did view_skills - made a new view_skills2 routine. bonelore and mapmaking are gone.
* order everyone: gets goto location, target, or who to follow just once, instead of once for each party member ordered.
* fixed: didnt set bedding's world object ID when resting on bedding.
* DONE: dont let 2 BMs use the same bedding at same time. when select bedding, need to check all other bm's for bedding action with that bedding, if found, show msg saying someone is already using that bedding.

DONE: WATER and WATERSKINS:
* improve how water and waterskins work. move the water with the container.
make sure they have sufficient waterskins whenever they transfer water. store in pit, drop on ground, fill waterskins (water source or rain), give water to bm, pickup dropped, etc.
when they transfer a waterskin, transfer water as needed. dont let them drop water. only let them drop water in waterskins. abandon water as requierd if they abandon waterskin.
need to possibly mod calls to add2inventory and add2stufflist. fill waterskin watersource, fill waterskin rain, give water to bm, npc menu (trade, ask for item), trade with band (get water).
* fill waterskins and fill waterskins rain check for waterskins full and max encumberance at start of action handlers. fill waterskins didnt check encumberance until water was gathered. fill waterskins rain didnt check it at all!
* all fill waterskin from water source actions now use try_fill_waterskins.
* made sure fill waterskins and fill waterskins rain check for player has waterskins. so now - for sure - they can't gather water without waterskins. can only get it from storepit, other BM, NPC, or trading with a friendly band.
* checked: get stuff from storepit makes sure they can carry water before giving it to them. so it makes sure they have enough waterskins.
* store stuff: checks for waterskins in the pit, and not all full. now you cant store water in a pit that doesnt have non-full waterskins.
* drop object: no longer lets you drop water. tells you to drop a waterskin instead.
* checked: pickup dropped object calls can_carry, which check encumberance, container capacity, and waterskin capacity. so they can't pickup dropped water without a non-full waterskin.
* newtrade and trade_with_band: doesnt let you trade for water if you dont have non-full waterskin.
* ask for item: doesnt give water if cant carry
* trader hut: doesnt trade for water if cant carry
* give_item2bandmember: doesnt give water if cant carry
* getstuff and storestuff: transfers water as needed when get/store waterskin.
* give_item2bandmember: transfers water as needed when give waterskin.
* trade_with_band: removes water as needed when trade away waterskins
* new_trade: removes water as needed when trade away waterskins
* trader_hut: removes water as needed when trade away waterskins
* fixed: some calls to indexdropat checked for return of 0, not -1 on error.
* indexdropat activates new record for each waterskin dropped. no longer adds waterskins to existing active records. so each active record with a waterskin has only one waterskin, and data[0] can be used to store how much water is in it.
* drop object: transfers water to dropped waterskin as needed. amount of water is stored in waterskin worldobj[].data[0].
* abandon object: removes water as needed when abandon waterskins
* transfer_to_waterskin_as_needed: calcs avg qual of water transferred, and stores it in worldobj[].data[1]
* pickup_object: if object is WATERSKIN, checks encumbrance vs waterskin+the water in it, and transfers the water with the waterskin, if they can carry both the waterskin and the water in it.
--- END WATER AND WATERSKINS CHANGES ---

* DONE: turn clip ranges and autocliprange on again. this also fixed: clip rng for animals too far compared to clip rng for terrain chunks.
* cant see small dead animal under the water. draw them at y = 0. dead animal in water are now drawn at y=0 (water level) - IE half floating in the water.
* 3pv cam, make min altitude ground + a few feet so its above ground coverage. defined MIN_ALT_3PV_CAM. set it to 3.0f (three feet). old hard coded value was 1 foot.
added it to set 3pv cam for: cave, cavern, outdoors, perm shelter, rockshelter, and hut.
* make anis: need different y's for male and female.
* dawn & dusk are a little to dark. they are now lower limited to nighttime lightness.
* fixed: doesnt do fire light in adjacent map sq
* make 3pv cam look over avatar's rt shoulder
* sleep ani - draw at different heights dependingon has bedding
* dont draw avatar in 3pv if player is looking almost straight up.
* make sure accel time display, tutor messages, hud, etc dont overdraw each other.
* already done: not stop and start anis correctly when NPC joins band?
* already done: view inventory: flush sprites before drawmouse
* sleep on bedding: make them line up on the bedding. adjust location and orientation.
* dont play rain sfx when snowing
* doesnt play fire sfx in adj map sq. typo bug. called dist w/ mx,mx,x,z, not mx,mz,x,z.
* view stats - only play klick when they click on the done or rename buttons.
* add tada sfx to game saved.
* make animals do sliding collisions
* already done during playtesting: show all BMs on local map
* make mouse wheel zoom world map in and out.
* reinit dice from time to time. now calls initdice once per game day.
* more animals ? double the base chance of animal encounters?
increased by 10x. try it and see...
* more water. rocks etc?
water: every map sq, to once every 10-100 map squares
rocks:
chert, flint: 28% of land = 1 in 3.57 map sq's on avg.
obsidian, quartzite: 1 per 230 map squares (mtns & volcanos only)
volcanoes: one per 4600 map sq on avg. in lines along plate boundaries.
tar: seeps from underground oil deposits which cover perhaps 10% of the planet. = 1 in 10 map sq's on avg.
* talk to caveman: ask directions to rocks, berry bushes, good hunting grounds, etc. a simple goto location quest. getting there is the reward. talk to cavemen: ask directions to water, woods, rocks, etc. do they always know where stuff is? do they always tell you? do they sometimes tell you a bogus location? can you ask them more than once and get a different response?-no
+ trade maps w/ npcs, will they trade? do they gve you a bogus map? can you trade more than once and get different maps?-no
+ npcs: ask whats around: do they always know? will they tell always you? do they sometimes give you bogus info? can you ask more than once and get a different response?-no
+ combine ask directions, whats around, and trade maps, and what do you get? an extended whats around. npc: exchange knowledge of area. caveman: ask whats nearby - automaps everything in a 1 or 2 (or more?) map square radius around the player. not as realistic as tracking what each npc knows, wheter they will tell you, if they give you bogus info, if you've already asked them, etc. so you need flags for "what they know", and "if you've asked them already" for each thing you can ask them (where's rocks, water, wood, whats to the north, etc)
+ simpler - relations governs if they tell you or not, and it reveals world map in a 2 map sq rad (for example) on success, and nukes relations some on failure. but can ask again, (with ever decreasing chance of success due to ever decreasing relations from repeatedly asking ; ) ).
+ or would early humans freely share such knowledge? friendly caveman: exchange knowledge of local region. why wouldnt they? resource competition? not in early stages when resoureces where plentiful. cant see why they wouldnt share knowldge of local area. it would automap say, everything in a 1 map sq radius around current location - world and local maps - completely - IE entire local maps revealed.
* talk to cavemen, ask if you can travel with them. - if yes...then what? you can follow them around -whooptie do! if no...then what? they throw rocks at you to keep you from following them? i mean - hey, its a free planet - right? if you happen to go where they do, as long as you dont interact with tem and nuke relations, no biggie. - or- you become their companion, and must hang out near them, and they fight with you, and give you orders. go here, wait, attack that, etc. but a nearby friendly will generally fight with you. so ask to travel with may not be needed. you can just follow them if you feel like it.
* add dismiss follower action
* already done: encounters don't correct for encounter location in adjacent map sq when player near map sq edge.
* "move storepit" added to playtest menu
* fixed: Zdomessages, getmouse, and mouse wheel. now fps view and world map both zoom with mouse wheel.
* grogs game converted to new savegame format.
* new world map generated for grogs game. moved the base camp. added new huts and bedding. moved all storepuits. abandodned empty storepits.
* finished converting grogs game to new world map. demolished all old huts and bedding. now they're all at the new camp, making arrows, gathering wood, or sleeping.
* made BM vs BM and BM vs NPC relations go to zero over time
* followers: take shares. original version, followers took a share of hides, meat etc from kills at the end of fps combat mode. now follower reations go down over time. if < 50, they leave your party. so you have to give hides etc to keep them in your party.
* types and numbers of animals at crh's is not persistant. when gen encounter, have to set type and num. when one dies, reduce num. added animal_type and num_animals to crhrec. added is_crh_animal and crh_num to animal rec. if game does cave or rocksheletr animal encounter, if crh2.num_animals<1, it generates crh2.animal_type and crh2.num_animals. else it uses the current values. when an animal is killed, if animal.is_crh_animal, crh2[animal.crh_num].num_animals--.
* eruptions: should be 10% chance per year per volcano of 1 eruption. = 10/365/24% chance per hour for a given volcano. reduced from one per week on avg to ~10% chance per year, specifically: 11 in 1000000 per hour.
* improve timing of state changes in graze AI. reduced chance for state changes by factor of 10. flock rng changed from 50 to 25*animaltype.rad.
* make int have greater effect on time and chance to make and fix stuff. some of this is already done, but not all make and fix actions. make int affect time, chance, and qual of all items made or repaired. also added adjust for dex as needed.
ALREADY DONE:
makeobj
learn
fix_object
build_playerhut
repair_playerhut
makeobj2
repair_world_obj
repair_trap
teach bandmember (learners int only, not teachers)
FIXED:
makefire
cook
make_shelter
repair_shelter
make_bedding
makebedshelter
fixbedding
make_storepit
repair_storepit
make_raft
repair_raft
poison wpn
find_object
addwood2fire
forrage
train (w/ wpn)
learn_from_caveman
teach_caveman
learn_sailing
apply_camo
* improve avian ai. fixed: move_avian set y to ground height! made "orders: maintain distance" use new maintain_distance AI code. made avian AI code match animal AI code. collapsed some redundant code into single stand alone function calls.
* drop object doesnt handle dropping objects across a map sq edge into the next map sq! need to normalize dropat location rel to cm0. either that or remove distant dropped doesnt work across map squares. fixed: drop_object now normalizes drop location. any_BM_near_worldobj: added check for BB map sq dist < 2. it already handled map sq edges in other respects.
* game doesn't model bedding weathering, just wearing out from use.
* fixed: bedding.data[0]=is_in_shelter, bedding.data[1]=shelter_num, shelter.data[0]=has_bedding, shelter.data[1]=bedding_num
* make teachers int affect "teach bandmember" action.
* fixed: bm_in_way_of_bm: call to BBdist: typo: was mx1 mx1 mx2 mz2, not mx1 mz1 mx2 mz2. duh! took all morning to find and fix. will check all calls to bbdist for similar typos. and calls to dist2!
* fixed: get_fire_sfx: typo in call to bbdist
* fixed: get_fire_sfx: typo in call to dist2
* checked all 174 occurances of BBdist for typos. only found the one in get_fire_sfx.
* checked all 68 occurances of dist2 for typos. get_fire_sfx was the only one.
* fixed: getstuff and storestuff: was if index==WATER, not if object[index].type==WATER.
* fixed: getstuff and storestuff: was "if index==WATER", not "if object[index].type==WATER".
* fixed: drop_object: was "if index==WATER", not "if object[index].type==WATER".
* fixed: too many encounters are elephants. now all 6 elephant types collectively have the same chance as any other single animal type of appearing in a given type of terrain. IE if there are say, 32 differnt types of common animals in a given terrain type, now just one will be "some sort of elephant". what sort of elephant is then determined based on the terrain type (not all types of elephants appear in all terrain types). this for example, reduced elphant encounters in savanna from 16% to 3% of all animal encounters.
* checked out skinned meshes. code looks doable. .x files look ok. truespace has rigged models ready to go. need to learn how to animate models in truespace.
* eat/drink: show a menu of edible inventory to choose from.
* make mouse wheel zoom world map faster.
* butcher: add bmsg(). added ": you butchered an animal!"
made all messages such as "you get some meat!" read ": you get some meat!". that should help keep things straight when the band is butchering kills after a hunt.
* automatically load last saved game if player dies (except in tutor). added to continue, new, and load.
* replace all calls to select_item with shift_select_item. now only repair_object and sell_to_trader actions have you select just one object at a time. only "select item to trade band for" needed to be changed. all others already used shift_select_item.
* implemented new zoom-able local map! : )
* more hotkeys for world map: arrow keys and numpad arrow keys to scroll u/d/l/r.
* more hotkeys for local map: arrow keys and numpad arrow keys to scroll u/d/l/r.
* fixed: 1pv w/ wpn drawn, or sprinting, can see 3pv avatar! code got screwed up when "dont draw avatar in 3pv when looking almost straight up" was added. this also fixed: still draws 3pv cam when look up
* fixed: 3pv cam is too far to the right. moved to from 1 foot to 1/2 foot right of center. #defined xofs_3pv_cam. made all six versions of set3pv cam use it. there are six versions to adjust to the six different types of complex environments in the game (outdoors, in hut, in rockshelter, in cave, in cavern, and in playerhut).
* girl sleep on bedding: bandmember y is too high. chnged from baseline_y-1 to baseline_y-1.5
* increase drawing clip rad of animal #30 small antelope. increased from 2 to 3.
* change loading screen to copyright 2015. made new loadmsg() routine.
* add ability to toggle between world and local maps
* test avian attack ai - not working right?
+ fixed: didnt call set_predator_tgt (weaker prey only) when hunting. it would target strong prey, then flee when close!
+ fixed: didn't call do_animal_attack when attacking! it would dive on a target correctly (the hard part), but not attack when it got there!
+ fixed: avians start their attack too late. doubled avian vs ground target start_attack_range from 30 to 60. makes perfect sense. the new AI attacks at sprint speed, not run speed - IE double the speed it used to. so now it needs to start its attack twice as far away. i love it when the physics works out correctly! now once again, if there are big hungry avian predators around, you'd better do something or you're going to die!
+ fixed: avians now land before resting due to fatigue
+ fixed: set xr (pitch) to zero when standing.
+ fixed: climb/dive vs avian tgt: it was setting desired_altitude to ground level at target's location for all targets, even avains. now it sets desired_altitude for avian targets to the target's altitude.
***** still need to test avian vs avain start_attack_range. in general, start attack range formula may need to get fancier, and take into account speed and direction of attacker and target, not just speed of attacker and range to target. stuff done to fix avian vs avian AI:
* renamed b2_avian_attack() to b2_avian_attack_ground_target(). B2_avain_attack() is tailored for ground attack.
* added b2_avian_attak_avian_target()
* added: b2_avian_match_targets_altitude() for use by avians against avian targets.
* fixed: draw_animal_model: if dead: if in water draw at water level, else draw at ground level.
was backwards: if in_water draw at ground level, else draw at water level. (oops!)
* fixed: didnt start to land to eat carcass until right above it. now: if not at carcass, but within within 50: if flying, lands, else fly a bit (towards carcass). landing starting at 50 put them close, fly a bit (which causes oscillation betwen fly and land, until at carcass) make them "hop up" to the carcass - just like a real bird.
* added instructions to the "create a new character" screen
* demo now starts player in temperate savanna terrain.
* end demo: removed references to atk to subdue and capture.
* tutor: added info about "z" key to pick up dropped objects
* turned off playtest hotkeys in demo
* increased cave hyena hp in demo so they attack player.
* tutor: gives encounter advice right after the normal encounter message - not right before.
* upatree: badguys dont leave! simply have them ignore targets that are up a tree. set_predator_target now ignores band members who are up a tree if the animal type can`t climb trees.
Norman Barrows
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!

https://sites.google.com/site/rocklandsoftware/home/cmbeta1

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
* adjustable diff levels for:
> hit points
> caveman encounter chance
> animal encounter chance
the game already has adjustable healing rate.
* 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.
* added trader encounters
* added ability to strip gear from dead bodies.
* more realistic gear loadout for npc's, including small chance for artifact.
* added thief encounters.
* 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)
* removed "bury" from dead caveman menu
* 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!
Norman Barrows
Caveman 3.0 Beta 18 released!

HEURISTIC COLLISION AVOIDANCE, BACKGROUND TERRAIN CHUNK GENERATION, SOUND DETECTION STEALTH MODELING,
UNLIMITED SAVE GAMES.

Play now!
http://rocklandsoftware.net/beta.php

Game homepage:
http://rocklandsoftware.net/Caveman.php



New for Beta 18:
___________________________________________


* added heuristic collision avoidance to AI
* added background terrain chunk generation.
* added sound detection modeling to stealth modeling. chance of detection based on whether you're moving, terrain type, and stealth skill experience points.
* game now plays combat music when player is hunting non-hostile animals: IE when wpn drawn and wild animal within 40 feet.
* added "select file" screen for loading games.
* added automatic save game file name generation. this along with "select file" for loading allows for practically unlimited saves of a game
(up to 4.2 billion or so per save name, or the limits of disk space).
* added drumroll sfx to important messages: succes or failure on make or repair or learn. kill with hand or missile wpn, all encounters, taking damage, death, getting sick, recover from illness, all damage heals, etc.
Norman Barrows
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
adjust brightness.

* textures
i created a textures database. a simple array of d3dx9 texture pointers.
it includes routines for creating, loading, and saving textures.
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 a menu to be displayed. it then calls Zaddmenu(option_text)
to add text for menu options it then calls pick=menu(num_options)
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:
// Z3D.h #ifndef z3d_h#define z3d_h #include #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers#include #include #include #include //####################### PUBLIC GLOBAL DEFINITIONS ################################## #define pi D3DX_PI //################## PUBLIC GLOBAL VARIABLES ##################################################### extern HWND Zprogram_window_handle; extern int Zalphatestlvl; extern int mousewheel; // d3d font objectsextern ID3DXFont *pFont;extern ID3DXFont *pFont2;extern ID3DXFont *pFont3; // d3d sprite objextern ID3DXSprite *Zsprite; extern D3DPRESENT_PARAMETERS Zparams;extern LARGE_INTEGER Ztimer_freq; extern int Ztrace[20]; extern DWORD Znum_verts,Znum_primitives; extern int Zcurrentmesh,Zcurrenttex; extern int old_mousex,old_mousey; //######################### MATERIALS ##################################### #define ZMAXMATERIALS 10 extern D3DMATERIAL9 Zmaterial[ZMAXMATERIALS]; void Zsetmaterial(int materialID); void Zinit_materials(); void Zload_materials(); // load materials from materials.dat file //############################# MENU STRINGS ################################### #define MaxMenuStrings 50#define MenuStringLength 100 extern char Zmenu[MaxMenuStrings][MenuStringLength]; // menu stringsextern int LastMenuOption; void Zgetstring(char *s,char *s2);int Zdomenu(int mousetex);void Zclearmenu();void Zaddmenu(char *s);void Znewmenu(char *s); // clear + addint Zmenu_char_width(int i); // returns menu width in chars //############################# SPRITES ###################################### extern ID3DXSprite *Zsprite; // d3d sprite obj void Zbeginsprite();void Zendsprite();void Zdrawsprite(int texID,int x,int y,float sx,float sy); // x,y are UL corner of spritevoid Zdrawsprite2(int texID,int x,int y,float sx,float sy,float rz); // draw a rotated sprite. x,y are screen coords of the center.void Zflushsprites(); //########################## tex DB ############################################ #define Zmaxtextures 400 struct Ztexrec{char name[100];LPDIRECT3DTEXTURE9 tex;}; extern Ztexrec Ztex[Zmaxtextures];extern int numtextures; void Zloadtex(char *s);void Zloadbitmap(char *s);void Zloadsprite(char *s);void Zload_dynamic_bitmap(char *s);void Zloadspritetex(char *s); // alpha transparencyvoid Zloadspritetex2(char *s); // alpha transparency, 5 mip lvls in dds file.void Zloadspritetex3(char *s); // colorkey transparencyvoid Zunload_last_bitmap(); void Zload_textures(); //########################### mesh DB ########################################### #define maxmeshes 300 struct Zmesh{IDirect3DVertexBuffer9 *vb;IDirect3DIndexBuffer9 *ib;int numverts,numfaces;}; // meshDB recordstruct meshrec{char name[100];//LPD3DXMESH mesh;Zmesh mesh2;}; // mesh DBextern meshrec mesh[maxmeshes]; void Zloadmesh(char *s,int dynamic); // dynamic = 0 or 1. extern int DBnummeshes; void Zload_meshes(); void optimize_meshes(); //######################### DRAWLIST ################################################# struct Zdrawinfo{int type, // 0=mesh, 1=model, 2=2d billboard, 3=3d billboardmeshID, // for models: modelID texID, // for models: aniID alphatest,cull,clamp,materialID,rad,cliprng,data[5];float sx,sy,sz,x,y,z,rx,ry,rz,range; // range is rng to camera. not currently used.D3DXMATRIX mWorld;}; extern int Znumdrawrecs;//extern int alphatest_numdrawrecs; void Zcleardrawlist(); void Zcdi(Zdrawinfo *a); // "ZClearDrawInfo". memset's a Zdrawinfo struct to 0. void Zdraw(Zdrawinfo *info);void Zdraw2(Zdrawinfo *info);void Zd(Zdrawinfo *b); // draw mesh, model, 2d billbaord, or 3d billboard void Zdrawlist(); void Zpresent();int Zshowscene(); // 1=success 0=failure //############################# models ################################################### #define maxlimbs 20 // limb recordstruct limbrec{int parent,meshID,texID,alphatest; // parent = index of parent limb. -1=no parent.float x,y,z,xr,yr,zr,sx,sy,sz; // location of limbs origin (in parent's coords). current orientation of limb.float xr0,yr0,zr0; // "at rest" orientation of the limbchar name[20];}; // model recordstruct modelrec{int numlimbs;limbrec limb[maxlimbs];char name[20];}; void Zdrawmodel(Zdrawinfo *info); // meshID=modelID. uses x,y,z,xr,yr,zr.void Zdrawmodel2(Zdrawinfo *info); // meshID=modelID. uses mWorld. //################################### models datatbase ########################################## #define maxmodels 200extern modelrec model[maxmodels];extern int nummodels; void loadmodel(char *s);void savemodel(int modelID,char *s); void Zload_models(); // load models from models.dat file //####################### animations ################################################ #define maxkeyframes 20 // a 3d vector (position, orientation, etc)struct xyzrec{float x,y,z;}; // keyframe recordstruct keyframerec{int numframes,numlimbs;xyzrec rotation[maxlimbs];}; // animation recordstruct anirec{int numkeyframes;keyframerec keyframe[maxkeyframes];}; int startani(int aniID,int modelID);void stopani(int playerID);int set_animation_frame(int playerID); // animation player recordstruct aniplayerrec{int active,aniID,modelID,curkeyframe,curframe;}; #define maxaniplayers 200 // animation playerextern aniplayerrec aniplayer[maxaniplayers]; //############################ animations DB #################################### #define maxanimations 200 extern anirec animation[maxanimations];extern int numanimations; void loadani(char *s);void saveani(int aniID,char *s); void Zload_anis(); // load anis from anis.dat file //########################## MATRIX MANIPULATOR ################################ extern D3DXMATRIX Mmat;void Mstart();void Mrotate(int axis,int degrees);void MrotateRADS(int axis,float radians);void Mmove(float x,float y,float z);void Mscale(float x,float y,float z);void Mtrans(float *x,float *y,float *z); // transform point x,y,z by matrix Mmat //#################### STRING MANIPULATOR ################################# extern char S[1000];void Ss(char *s2);void Sa(char *s2); // string add intvoid Sai(int i); // string add floatvoid Saf(float f); //###################### GRAPHICS ENGINE ######################################### const DWORD ZFVF=(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0) ); // D3DFVF_DIFFUSE | D3DFVF_SPECULAR | /*struct Zvertexrec{float x,y,z;float nx,ny,nz;float tu,tv; DWORD diffuse,specular;};*/ struct Zvertexrec{D3DVECTOR position,normal;//D3DCOLOR diffuse,specular;float tu,tv;}; extern IDirect3DDevice9 *Zd3d_device_ptr; extern D3DXMATRIX ZmView; // view matrixextern D3DXMATRIX Zprojection_matrix; // projection matrixextern float Zcamx,Zcamy,Zcamz,Zcamxr,Zcamyr,Zcamzr; // camera position int Zinit(HINSTANCE program_instance_handle,int width,int height,char *progname,float nearplane,int farplane); // ,int zbuf24bit);void Zshutdown();void Zsetlite(DWORD liteID,float x,float y,float z,float brightness);void Zsetcam(float x,float y,float z,float rx,float ry,float rz);void Zsetcam2(float x,float y,float z,D3DXMATRIX *m); // m is rot matrixvoid Zclearscreen(int r,int g,int b);void Zclearscreen2(); // clears screen to z game engine default color (blacklight)void Zclearzbuf();void Zbeginscene();void Zambient(int r,int g,int b);void Zlighting(int onoff);void Zalphablend(int onoff);void zbuftest(int onoff);void zbufwrite(int onoff);void Zcull(int onoff);void Znormalize(int onoff);void Zlite(DWORD liteID,int onoff);void Zalphatest(int onoff);void Zmipmaps(int onoff);void Zclamp(int onoff);//void Zanisotropic(int onoff);void Zminmagfilter(int filter_type); // filter_type: 0=point, 1=linear, 2=anisotropicvoid Zspecular(int onoff); int Zsuperclip(int x,int y,int z,int rad,int cliprng); void Zset_clip_planes(float nearplane,int farplane); void Zcalc_frustum_planes(); // must set proj and view mats first! int Zsuperclip2(int x, int y, int z, int rad, int cliprng); // must call Zcalc_frustum_planes first! int Zarea_in_frustum(int x1,int z1,int x2,int z2); // must call Zcalc_frustum_planes first! void Zsetmesh(int meshID); void Zcreate_mesh(int vbsize,int ibsize); void Zsettex(int texID); void Zdrawimmediate(Zdrawinfo *a); void Zdrawimmediate2(Zdrawinfo *a); // uses Zdrawinfo's mWorld mat void Zcalc_frustum_planes2(); // rotation only //############################ TEXT ######################################## void Ztextcolor(int r,int g,int b);void Ztext(int x,int y,char *s);void Ztext3d(int x,int y,char *s);void Zsetfont(int font); // 0=comic ms sans 1= ariel 2=times new romanint textwidth(char *s); // returns width of string s in pixels. uses current font setting. //################################ MOUSE ######################################### void Zgetmouse(int *x,int *y,int *b);void Zputmouse(int x,int y);void nobutton();void pause(); //########################## WINDOWS MESSAGE PROCESSOR ############################ void Zdomessages(); //########################### GENERIC GUI COMPONENTS ################################### void Zmsg(char *s,char *title);void Zmsg2(char *s); //############################ KEYBOARD ########################################## int Zkeypressed(int vkey); //####################### STRING CONVERSION ROUTINES ############################# int s2i(char *s);void i2s(int i, char *s);void f2s(float f,char *s);float s2f(char *s); //############################ DICE ###################################### int dice(int a);void initdice(); //####################### TIMERS ######################################## void Zstarttimer(int a);int Zelapsedtime(int a);int Zelapsedticks(int a); //####################### FILEIO ########################################## // general int filefound(char *s);int filesize(char *s);time_t timestamp(char *s); // returns file create time (UTC format: secs since 1970). returns -1 if file not found.void closefile(FILE *f); // text file i/o FILE* infile(char *s); FILE* outfile(char *s); int readfile(FILE *f,char *s); // returns: 0=fail 1=successint readfileint(FILE *f);float readfilefloat(FILE *f); void writefile(FILE *f,char *s);void writefileint(FILE *f,int i);void writefilefloat(FILE *f,float i); // binary file i/o FILE* infilebin(char *s);FILE* appendfilebin(char *s); FILE* outfilebin(char *s); int readfilebin(FILE *f,unsigned char *buf,int numbytes); // returns numbytes readint readFBint(FILE *f);float readFBfloat(FILE *f); void writefilebin(FILE *f,unsigned char *buf,int numbytes);void writeFBint(FILE *f,int a);void writeFBfloat(FILE *f,float a); //####################### GENERIC MATH ROUTINES ############################# int isin(int x,int y,int x1,int y1,int x2,int y2);int dist(int x1,int z1,int x2,int z2); // diamond bounding box distint dist3d(int x1,int y1,int z1,int x2,int y2,int z2);int BBdist(int x1,int z1,int x2,int z2); // sq bounding box distfloat deg2rad(float deg);float rad2deg(float rad);int heading(int x1,int z1,int x2,int z2);int relheading(int x1,int z1,int h1,int x2,int z2);void llim(int *a,int b);void ulim(int *a,int b);void limit(int *a,int b,int c); // 0 degrees = up. 90 degrees = forward. 180 degrees = down. int angle(int x1,int y1,int z1,int x2,int y2,int z2);int rng2D(int x1,int z1,int x2,int z2);int BBdist3d(int x1,int y1,int z1,int x2,int y2,int z2); // 3d bounding box distancevoid normangl(float *a); // normalize angle to 0 to 2 pifloat rng3d(float x1,float y1,float z1,float x2,float y2,float z2); //################################ TEXT COLORS ############################### void redtext();void greentext();void bluetext();void yellowtext();void magentatext();void cyantext();void whitetext();void blacktext();void greytext(); // ################################### mouse aimed camera ################################### void Zresetmouse(); extern float cam_xr;extern float cam_yr; int Zmouse_aim_camera(); // returns mouse button pressed: 0 none, 1 LB, 2 RB, etc. // load meshes and textures using a list of filenames stored on disk in a text file //################################## SCREEN DUMP ############################################## void Zscreendump(); //############################ TARGET LIST ######################################################### // #################################################### TARGET LIST DATA STRUCTURES ##################################################### #define stepsize 0.1f struct ttyperec // a target type record{float maxspd,turnrate;int ai,rad,hp,mass,canfly,userID,value,animated,usefuel,maxfuel;Zdrawinfo d;}; struct tgtrec{float x,y,z,xr,yr,spd;int type,dp,owner,fuel,alive,active,userID,aniplayerID,dontdraw;}; #define maxttypes 50#define maxtgts 200 extern ttyperec ttype[maxttypes]; // target types database extern tgtrec tgt[maxtgts]; // targets database extern int numtgts; // index of last active tgt + 1. // max possible number of active tgts at the moment. // search tgt list using: for a=0 a


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/
Norman Barrows

AI in Caveman

Caveman ai:

ai in caveman has been through three major versions.

the first version was just quick and dirty code to get things going. like
all code of this type, it quickly grew and evolved into an ugly mess.

the second version of the ai was a more traditional setstate/runstate
type affair. setstate selected one of about 14 or so AI states for an
entity, depending on what was going on. runstate was a big switch
statement that executed the code for the various states. one problem
with the traditional setstate/runstate model is that it only has one
state variable. so if you have multiple states at once you must have
different states for each combo.

the third and current version of the AI uses a different approach.

it uses prioritized condition checks to determine what to do. as soon as
a condition is found it should react to, it does so, then returns. no
setstate/runstate. as soon as condition is found, the equivalent setstate
is therby determined and the appropriate runstate code can be immediately
executed.

it also uses multiple AI state variables (mostly booleans) in lieu of a
single AIstate variable as in setstate/runstate. so it has AI state
variables like in_collsion _recovery, in_collsion_avoidance,
taking_missile_fire, orders (goto, attack, follow, etc.), and so on.
this allows an entity to be in multiple states at once such as:
"in_collision_recovery" while moving to attack due to
"taking_missile_fire" while "following" another entity. when they finish
collision recovery, they resume moving to attack. when done attacking,
they resume following the entity. without the need to push and pop states
on and off a state stack. the condition check priorities cause them to
automatically resume a lower priority state once a higher priority
state is no longer in effect.

the prioritized condition checks work as an expert system.
the condition handlers (code) in turn are each mini expert systems in
handling their condition. implementation varies depending on the condition
being handled. most are rule based systems. some are state machines. the
handlers in turn may call even lower level expert systems for tasks such
as selecting best weapon to use, etc.

all told, the game implements about 18 different types of ai depending on
the entity type and whose side they're on. so for example, AI for a pet
dire wolf is different from that for a wild, subdued, or captured dire wolf.
and AI for a traveling companion caveman is different from that of a neutral,
hostile, thief, hired warrior, or band member caveman.

there are four basic types of AI for animals:
1. defend - the animal will stand its ground and defend itself if approached.
2. maintain_distance - the animal will attempt to maintain a safe distance
from all threats. if approached, it will flee.
3. attack - the animal is predator. when hungry it will go hunting, feeding
on nearby carcasses if available, or attacking other animals not bigger than
itself. when not hungry it just hangs out.
4. defend_location - the animal will defend a specific location in the game
world. used by quests where animals guard treasure. if far from the
location, the animal will move to the location. if at the location, it will
attack all who approach.

Avian AI is completely separate from that for ground animals, although it
takes the same form.

All animals include "graze" as one of their possible AI moves. its usually
the last choice - IE when there's nothing more important to do.
"graze" cycles between stand, wander, flock, and migrate states periodically
at random. its an example of a condition handler that uses a state machine.
wander simply moves to a random wander_to point. flock moves towards the leader
(the first animal of a given type appearing in the entities list). in the case
of the leader, flock becomes stand. migrate is only used by the leader. the
leader moves off in a migrate_direction determined by the type of animal (so
they still migrate the same direction even if the leader is killed). if a
leader is killed, the next active animal of that type becomes the new "leader".

note that leader migration behavior in combo with flock behavior leads to emergent herd migration behavior! ; )

model the little stuff right and the big stuff happens on its own! - well at least sometimes - if you do it right.

multiple AI states vs setstate/runstate is another example of this. by tracking _multiple_ states (which setstate/runstate does not do) - IE by modeling state in greater depth than setstate/runstate - you automatically get emergent push-state, pop-state type behavior with no pushing, popping or state stack required.
Norman Barrows
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
thats it. i was already familair with dx8, and hadn't learned
shaders yet - i hadn't needed them. still haven't really learned
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 /
import / export headaches.




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
arrows. having paid $1000 for the sound effects
library, i was bound and determined to get my money's
worth out of it. so i used the box as the mike stand
while i recorded the sound of me firing the bow down
the hallway in the house! .

up next:
step one, getting a handle on directx graphics.

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

part 1:
https://www.gamedev.net/blog/1730/entry-2259487-the-building-of-caveman-part-1/
Norman Barrows
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.
Norman Barrows
The Building of Caveman, Part 1

in this series of posts i will explain the process of making the game
Caveman v3.0.

What was done and why.

this is done in hopes that it may help others in their quest for success.

first, who i am:

i'm life long gamer.

as a little kid (before computers!), wargames facinated me.
that big hex map with all that terrain, and all those unit counters! and the
dice and the charts! WAY too cool! there was something seriously cool going on
here!

then there were arcade games like "night bomber", a very rudimentary
b-58 hustler flight sim arcade machine. it had a backlit plastic 3d
conveyor belt of plastic for the ground mesh, and used some sort of illuminated
platic for the missiles in flight. then it was mirror projected to the view
screen of the cabinet. explosions were backlit under the "terrain mesh".
i can still remember the "shoo,shoo,shoo - booom, boom, BOOM!" sound effect
it made when you cut loose with a salvo of missiles. . i was so little i
had to stand on a stool to play!

later came D&D, then Traveller, then both at once! Two years as president of
the wargame club in high school. I also designed few table top games during
this period. There was a super RISK type wargame with land, sea, air and
carrier units, land, sea, and air bases, and land sea, and air zones for
movement. There was a sharship combat game, turn based strategy with carriers,
battle crusers, fighters, and such. and there was a simple futuristic RPG
inspired by the first star wars movie, set in a huge abandoned space station,
the rules of which were made upduring one of those rpg club convetions a
friend took me to once. Everyone always wanted to play in my D&D world, i was
almost always the DM, seldom got to be a player, but i learned as a player
from a great dm (thanks John Durfee!). i learned one of my first and best
game design lessons there: NO MONTY HAUL!


About the same time, i took my first
programming class (sophmore in high school i think it was). interperted
basic on an ibm 360 mainframe accessed remotely via 3 dumb tremials and a
teletype terminal, each running at 1200 bits per second. . I wrote a
turn-based clone of the arcade game "lunar lander" on that system. you'd
input your x and y thrusts, and then it would draw the next frame .
You should have seen how many trees i killed when i ran it one time on the
teletype terminal. to clear the screen and draw the next frame, it did a page
feed. so every frame printed an entire page on an 18" wide line printer
teletype terminal. the classroom was awash with printer paper! .

after high school, i used my buddy's mom's pc to write a text and vector
graphics turn based D&D game. it was a sperry rand pc with 64k, 2 360k
floppies and a CGA card. interperted basic on dos 2.11.

a couple years later i got my first pc, an 8khz 8088 overclocked to
10khz. word was, for second year physics lab, even if your experiment was
unsucessful, if you could write it up correctly with all the charts and
graphs etc in a word processor, "real professional like", you got an A.
so that was my justificsation for getting a pc. now adays its almost
de-regeur, i'd assume. at first i wrote a few apps in basic: text editor,
autoscheduler, quicken-type software, etc. and "flying saucer shooter" -
think missile command vs flying saucers, and you get ground based lasers.
my first realtime arcade game!

then i got into developing operating environments and integrated packages
(look them up!).I learned how to write just about every kind of app.

flash forward about 6 years. By this time i had almost completed my
software engineering degree at OSU (i switched from aerospace when the
cold war ended). i had worked as a systems analyst for the air force
as my engineering co-op, specializing in needs analysis and puchase
recommendations for executive information systems software (looks it up!).
i had also worked for the OSU school of medicine dept of anatomy where i
specialized in needs analysis and purchase reccomendations for
multi-media computer network systems (they were putting Gray's anatomy
online for the first time ever anywhere - in high resolution full
living color).

one day, me and a buddy were DLing Star Trek games, and they were all
the same top down view, sector quadrant, turn based text mode trek game.
i said, "I could write something better than that!" - and in six weeks, i had.
showed it to my friends. they said, "looks cool! needs better
explosions!" (you know how players are! ). so i added better explosions.

then i sent an email to the sysop of the biggest BBS at OSU, and asked him
very politely how he thought i ought to distribute it. he replied that the
model recently established by a new game called "castle wolfenstein 3d",
where you gave them a little for free (about 5% of the game - roughly $1
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/












,
Norman Barrows
While I wait for a build, I thought I'd do a quick update. Its been too long since I posted a progress report.

I've been play testing the game a lot recently. About one game year so far with the same play test character (Grog).

I've gotten perhaps half of the screenshots from that posted.

Play testing revealed no major problems. A few things to tweak and adjust. One I make those changes I'll post a new beta.

One big change is that attack to subdue is out, and "dances with wolves" is in.

Domestication of animals has been totally re-designed to be more realistic.

No longer do you attack to subdue, capture with rope, then tame with meat, for any animal you can catch.

Now, you drop meat, and dire wolves will eat it. Dire wolves have been reduced in hit points to just less than humans, so they won't target humans as prey. And they will flee if apprached too closely. relations with the wolf increase by the quality of the meat dropped. when relations go over 1000, the wolf "adopts" the closest band member at the time, and will begin to follow them around - at a respectable distance. dropping more meat will continue to increase relations with the wolf. when relations go over 2000, the wolf will allow the band member to approach. then the player can select the wolf and get the "dire wolf" menu. just one action: give meat. when the player gives the wolf enough meat to increase relations over 3000, the wolf becomes tamed, and fights at your side just like any other follower.

I'll post a proper update with details, and the rest of the screen shots soon. I'm torn between needing to keep the world abreast of progress on the game, and needing to finish the darn thing!

Back to dancing with wolves!
Norman Barrows
Building a large procedurally genrated world with no load screens:
How caveman 3.0 works.
======================================================================


GAME WORLD DATA STRUCTURES:
=====================================================================


1. the world map
---------------------------------------------------------------------
the world map is stored in a 500x500 array of structs.
each map square is 5 miles across.

terrain chunks and collisions maps are generated from the world map data.

assets are loaded once at program start. asset reuse is maximized.
load times are on the order of 20 seconds or so for EVERYTHING! : )

if required, paging of assets could be implemented.

the map structs hold info about elevation (heightmap used), vegetation
(what plants to draw, what ground texture tile set to use), water
(what water to draw), and miscellaneous terrain features, such as rock
outcroppings, fruit trees, berry bushes, tar pits, etc (more stuff to
draw).

the world map is randomly generated at game start, updated (changes)
once per game day, and is included in a save game.




2. pattern maps:
------------------------------------------------------------------------
so the world map tells us more or less what to draw, but not necessarily
where exactly to draw stuff.

enter "pattern maps".

a pattern map is a 2d array, either a true 2d array, or implemented as
a sparse matrix (a list).

so you have a pattern maps to tell you where to draw trees, rocks, etc.
pattern maps are then repeatedly tiled over a map square to place trees,
etc. The size of a pattern map should be big enough that no moiarre'
patterns are discernible within viewing range. this usually works out to
a size of two times visible range.

multiple pattern maps are used for different things so rocks and trees
for example don't all appear at the same locations.

pattern maps can contain more information that just location, they can
also include things like type information for determining drawing info,
or even render and physics info like scale, bbox dimensions, etc.

ground coverage plants can simply be draw every x number of feet with
type based on "location mod ".

caveman uses 5 pattern maps: one for trees, one for rocks, one for berry
bushes, one for fruit trees, and a generic pattern map for tall grass,
canyon heightmaps, and a few other things.

pattern maps are randomly generated at game start, and are included
in a save game.





3. The CRH list:
----------------------------------------------------------------------
the CRH list is a list of all the caves, rock shelters, and huts in the
game (IE all buildings in essence). an index is used to speed searches.
the index is a 2d array the size of the world map. for each map square,
the index holds a list of the CRH's in that map square
(IE their indexes in the CRH list).
the CRH list is randomly generated at game start, is updated once per
game day, and is included in a save game.






4. The world objects list:
-----------------------------------------------------------------------
this is a list of all the immobile objects the player has built in the
game world such as shelters, huts, landmarks, traps, bedding, etc.
it also includes all inventory objects the player has dropped. dropped
objects are only persistent inside player owned CRH's, otherwise they
are removed from the simulation when the player is no longer nearby.
so its ok to store them here without running out of room.






TERRAIN CHUNK GENERATION:
=======================================================================
when it comes time to render, the game determines the terrain chunks
in visible range, and draws each one. if a chunk is not in the cache
its generated on the fly. chunks are also generated in the background.

a terrain chunk is basically a pre-generated render queue list of all
the meshes in the chunk to be drawn, ready for sort on distance
(if desired), frustum cull and rendering.

a chunk is generated by clearing the cache slot, then adding meshes, then
setting the slot to active for use by the renderer.


the coverage and miscellaneous terrain features in a map square
determines what to draw, and the pattern maps are used to place items
such as trees, rocks, and plants.

the world map, pattern map, and world objects list determine the meshes
added to the chunk. once the meshes are added, the chunk is marked as
active for use by the renderer.

the optimal size for a chunk appears to be whatever visual range is.




ground mesh generation:
-----------------------------------------------------------------------
ground meshes are generated as follows:
pre-allocated static buffers are used.
the ground is composed of four interleaved meshes, one for each of the
four texture tiles used. a pattern map determines the texture used
by a quad. all quads using a texture are heightmapped and added to the
static buffers (VB and IB) for that mesh. the four meshes draw together
form one continuous ground mesh with tiled textures that still follows
the game's mantra of "one texture per mesh" for speed.

the elevation in a map square determines the heightmap used by the
ground meshes. elevations can vary from map square to map sqaure.
a "heightmap seam fixer" is used at map square edges. the ground
texture pattern map determines which texture a ground quad uses.







collision maps:
------------------------------------------------------------------------------
collision maps are generated on the fly, in a manner similar to terrain chunks,
and stored in a collision map cache.
the maps are 2d arrays of ints, with different values indicating different types
of obstacles: 0=none 1=rock 2=tree, etc.
collision maps are the same size as terrain chunks.
when a collision check is made, the location is translated to a collision map
and coordinates in the map. if the map indicates something there, true is returned
for the collision check.
if a collision map is not in the cache, its generated on the fly.
a maps is generated by clearing it, then adding trees, rocks, buildings, etc.
as specified by the world map, pattern maps, and world objects list. collision map
generation is faster than terrain chunk generation because it only sets a few ints
instead of adding a drawinfo struct to a database with a 2d index. so background
generation is unnecessary.





overall results:
--------------------------------------------------------------------------------------
as the player moves across the world, terrain chunks and collision maps are generated
as needed. right now there is a slight delay when a large number terrain chunks must be
generated in the foreground on the fly, but its too short to even display a
"generating area..." message. as i fine tune the background chunk generation to run
faster with more passes of less stuff per pass, and increase terrain chunk cache size,
and perhaps increase the background generator's look ahead range, i hope to eliminate
the slight delay entirely.

this approach gives you a procedurally generated random persistent modifiable game world
with no load screens.
Norman Barrows
The building of Caveman - part 6 - data structures

When i first got into programming as my major, my biggest fear was that I'd end up as a database programmer.
Turns out I became a gamedev. But i still have to do database programming. Sure, games are interactive
multimedia entertainment simulations, but underneath all that is - you guessed it - relational databases!
It turns out that a complex game can have a rather complex relational database system behind it.

Terminology:
database or list: a static array of structs, usually a one dimensional array.
record: a struct in an array
field: a variable in a struct.

In the game, most databases and lists are implemented as static arrays of structs. structs are referenced
via their array index. Maximum sizes required are known ahead of time, which allows the use of fast simple
static data structures. Many of the databases are relational, with some field (variable) in a record
(struct) being the array index of some other record (struct) in some other database (array of structs).
Some of the databases are nested, with one field in a record being an entire list. IE a variable in a
struct might be a whole array of structs. For example, each band member struct has a member varable which
is a list of active traps, implemented as an array of structs.

These are the data structures used by the game:

Asset databases:
First off, the generic databases for assets:
1. meshes - a VB and IB, numtris, and numverts.
2. textures - a d3d texture of some type
3. models - models simply refer to meshes and textures.
4. animations - a list of keyframes with limb orientations
5. animation players - a playback counter, plus model and animation references.
Caveman follows a mantra of one texture per mesh for speed. Models are made up of multiple meshes. An
entry in the models database references meshes in the mesh database, and textures in the texture database.
An entry in the animation players database references a model from the models database, and an animation
from the animations database. All asset databases are part of the generic Z game library used by Caveman.


Type databases:
1. actions - prerequisites, time required, chance of success, etc. prerequisites can include references to
skills and object types.
2. skills - prerequisites to learn, time required to learn, chance of learning success, etc. prerequisites
can include references to skills and object types.
3. object types - prerequisites to craft, weight, damage, cost, time to craft, chance to craft, etc.
prerequisites can include references to skills and object types.
4. animal types - hit points, turn rate, speed, etc. IE non-variable stats. animal types include a reference
to the models database, and references to the animations database.






single instance lists:
1. active bandmembers - an entity list for PCs. the player can tab between PCs at any time. Other PCs are
controlled by AI. each active bandmember has an inventory list, a list of active traps, a list of active
quests, and a list of active intoxicants. a bandmeber record has references to the following databases:
models (for body), meshes (for face and hair), textures (for skintone), and animations.
2. active animals - all NPC cavamen and animals (every non-PC entity). animals which are of type 2
(homo sapien) refer to an entry in the NPCs database where additional NPC specific data is stored.
animal records also refer to the animal types database, and the bandmembers list (for owners of pets).
3. active missiles - arrows, throwing rocks, etc. Smoke from fires may be implemented as a type of missile.
missile records refer to either the bandmember list or the active animals list (for owner), and also
refers to the object types database.
4. world objects - temporary shelters, storage pits, rafts, landmarks, dropped objects, etc. Basically
anything man-made except for huts. structs in this array reference the object types database.
5. active storage pits - a list of storage pits created by the player. refers to the world objects database
(a storage pit is a world object). includes an inventory list for each pit.
6. active rafts list - a list of active rafts. references the world objects database (a raft is a world
object).
7. NPCs - non bandmember cavemen. contains info on NPCs encountered by the player. references the
model, mesh, and texture databases. includes an inventory list for each NPC. NPCs at a CRH reference the
CRH list.
8. CRHs (caves, rockshelters, and huts) - a list of all the caves, rockshelters, and huts in the game -
83,000 of them! each entry has an inventory list (paged from disk). CRHs occupied by animals refer to
the animal types database. There is also a player's version of the CRH list, that only contains info
about CRHs the player has discovered.
9. player cave list - a list of those CRHs controlled by the player. references the CRH list. basically
an index of player controlled CRHs for use with the CRH database.



single instance matrixes (2d arrays of ints):
1. numconvos - tracks the number of conversations this day between band members and NPCs
2. relations - tracks relations amongst bandmembers, and between bandmembers and NPCs.



multiple instance lists:
1. inventory lists - list of objects carried, stored, or for trade. entires in the list refer to the
object types database. each bandmember, storage pit, NPC, and cave/rockshelter/hut occupied by
friendlies has an inventory list as one variable in their struct declarations.
2. Trap lists - a list of the status of active traps set by a band member. refers to the world objects
list (the trap is a world object). each band memeber record includes a trap list field (variable).
3. Active quest lists - a list of active quests. references the animal types database. each band member
struct has an active quest list.
4. Active intoxicants lists - a list of intoxicants currently affecting a band member. references the
object types database. each bandmember struct has an active intoxicants list.



handy structs used in the game:
i find that sometimes its handy to have a sturct to pass info around.
1. location - the world map is a 500x500 grid of map squares. each map square is 5 miles across.
a location is specifed by its map square indices (mx,mz) and by its d3d location in that map
square (x,y,z). a scale of 1 d3d unit = 1 foot is used. a location struct is a handy way to store
both the map sqaure and location of an object.
2. requirementsrec - a list of parts, tools, and skills required to do something. used by skills,
object types, and actions.
3. Zdrawinfo - all the info to draw a mesh, static model, animated model, 2d billboard, or 3d billboard.
used everyhwere to pass drawing info around.
4. objectrec2 - an inventory list entry: active, object type, quantity, quality, location. Used for
inventory and world object lists.





world map data structures:
1. the world map - a 2d array of structs. the world map is 500x500 map squares in size. a map square is
5 miles across. a location is specified by its map sqaure indices (mx,mz), and its d3d location in the
map square (x,y,z). a scale of 1 d3d unit = 1 foot is used. a maps sqaure struct contains info for
elevation, vegetation coverage, water, resources, etc. there is also a player's version of the world map
that only contians data for explored areas.
2. the local map - basically a 2d array of ints, used as booleans, explored/unexplored. This is used as
a "bitmap mask" to cover over unexplored sections of a map square when viewing the local map.
3. cavern maps - a 2d array of ints. values indicate walls, open space, encouter points, exits, etc.
4. plant maps - i needed a way to tell it where to draw plants, rocks, trees, etc. generating a bunch of
level maps was out of the question - too big for memory. what i came up with was what i call a "pattern
map". its a sparse matrix list of objects (trees, rocks, plants, etc). when drawing the scene, this
pattern map is tiled across the ground. Maps are large enough that no repetition is within visible range.
the game uses 4 such pattern maps - each one different - to place rocks, trees, berry bushes, etc.
4. wood grass map - another pattern map, for undergrowth in woods.
5. ground texture map - a 2d array of ints. caveman uses ground texture tile sets of 4 textures each. the
ground texture map contains random values 0 through 3, indicating which tile in the set to use for
texturing a ground quad. Agian, this "pattern map" is large enough so repetition is not within visible
range.
6. generic pattern map - as development progressed, i found myself needing a pattern map from time to time.
so i decided to create a generic one that i could write functions for that would return whatever i needed.
the geneic pattern map is a 100x100 array of random ints 0 through 100. functions are then written to
return values as needed. example: return the scale of a plant at x,z: map x,z to 0-99,0-99, and return
some permutation of the value in the generic pattern map at that location. Uses of the generic pattern
map include control of model, texture, scale, rotation, and offset of tall grass plants, and as the
basis for a double interpolated height map for canyons.




terrain chunks:
originally, the game drew the scene by brute force, drawing the ground one quad at a time, or with a dynamic
buffer, and iterating thorough the various pattern maps drawing tress and rocks etc, all the while checking
for collisions with man made objects (dont draw plants inside a hut!). Scene composition simply took too
long this way. So i stared at the lowest level and let that define how the code should work and how the
data should be organized. basically, what directx wants is an ordered list of renderables, sorted on
texture, then mesh, then near to far (for non-alpha). instead of generating the list of renderables each
frame, i decided to divide the terrain into chunks 300x300 d3d units (feet) in size. a chunk consists of
an unordered list of all renderables in the 300x300 area (in zdrawinfo structs), and a 3D index: a list of
textures, and for each texture, a list of meshes, and for each mesh, a list of instances which are indexes
into the list of renderables for the chunk. chuncks are genrated as needed and then stored in a cache with
LRU discard. to draw a chunk, the index is used to traverse the list of renderables in correct drawing order.
for each renderable, a frustum cull check is preformed, and if it passes, its added to the render queue.





the render queue:
the 3d indexed renerables list from chunks worked out so well that i redesigned the render queue in the Z
game library to use a 3d index. originally it was a simple list that got sorted just before drawing. Now,
as a renderable is added to the queue, its also added to the 3d index, in what is essentially a bucket
sort type of thing.




And that's pretty much it for the data structures. If i had to do it all over gain, i'd use more of a
composition type approach, and give animals and bandmebers a location struct for example. that way i
could write one piece of code to work with a location instead of one to work with bandmembers and one
for animals. As i go along, i try to do this with new code i write.

Note that almost everything is stored in ram. local maps use a cache and are paged to and from disk as
needed. Cavern maps are generated as needed, saved when you leave a cavern, and loaded when you
re-enter a cavern.


Part 5:
https://www.gamedev.net/blog/1730/entry-2260302-the-building-of-caveman-part-5-general-code-organization/
Norman Barrows
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!
Norman Barrows
So the next thing is to make the game draw animations when a band member is performing an action such as making a spear, starting a fire, gathering wood, practicing with a flint throwing hatchet, etc.

So for every action - and there are over 100 TYPES of actions - there will be an animation, and an animation object in hand, and zero or more animation objects on the ground.

And some actions such as cook, make, gather, repair, etc will use different objects in hand and on the ground, depending on whats being made, gathered, repaired, etc.

And the Learn action will required animations and objects in hand and on the ground for each skill in the game (about 50).

so every object (about 300) will have a make or find animation along with an animation object in hand and animation objects on the ground list. every object will also have drawing information, and a fixup translation and rotations for placing it in an avatar's hand. the fixup for each object will need to be determined experimentally in the modeler. the fixup locates the object with respect to the avatar's "weapon bone". its required because the size of an object at its "grip point" and its required orientation can vary.

and every action (about 100 types) will have an animation along with an animation object in hand and animation objects on the ground list - or use those for an object or skill.

and every skill (about 50) will have a learn animation along with an animation object in hand and animation objects on the ground list.



All the basic animations are in the game and hooked up for all actions. But actions that work with different objects (make, cook, etc), and learn, which works with different skills, all use the same animation for the moment.

i hope to make maximum effect of asset reuse. but the first thing i tried was drawing reeds in hand when gathering reeds, only to discover that i need a new asset (handful of reeds) because the best existing one (bundle of reeds) simply didn't look right. I decided to do that one later . My second attempt with the makefire action fared little better, as it will require its own custom animation - or two if i decide to actually show a fire bow when they use one.

so this item on the todo list is going to take a LONG time. its pretty much the last major thing left to do on the game project.


beyond that i'm down to adding better graphics, more actions, skills, and objects that were thought of late in the project, more animal types (i have no modern animals or sea creatures yet), and high level things like mini-games. Other nice things like a target browser.

so mostly nice features, add-ons, eye candy, and gold plating, but nothing that must absolutely ship in the first release.

which means, once i get the animations done and finish play testing and polishing, it should be ready to go! finally!
Norman Barrows
Caveman 3.0 Beta 14 released!

This is a late announcement. Beta 14 was actually released Dec 26th, 2014.

download:

http://rocklandsoftware.net/beta.php


game homepage:

http://rocklandsoftware.net/Caveman.php


new for beta 14:

* only plays combat sounds if source is within 75ft of player

* new action: abandon object: as drop, but removes object from sim.

* clears collision map cache when perm or temp shelter weathers away.

* enter shelter ani - draws higher off the ground.

* random music - adjust for gamespeed as to how often it plays. right now at high gamespeed it plays more frequently.
1 in 800 at 15 fps < 1 in 800 at 15 fps at 128x speed!
added bigdice()routine, goes up to dice(327,670,000) made music play if dice(100M) < 20000/turns_per_render

* don't let BM enter occupied shelter

* view inventory - alphabetize and sort on quality

* Fixed: bboxes for rocks are not correct. it now takes the rock mesh, and for each vertex, scales it and rotates it,
then checks it against the current bbox size (init'ed to zero), increasing the bbox as needed. so all verticies are scaled and rotated,
and the min and max x,y,z's of the results are the bbox corners.

* select item to trade: use shift select (shift-click for select 10, ctrl-click for select all).

* select item to trade: set select_object_offset to zero the first time, so the list is not scrolled down when they first enter the
select item screen.

* click sfx for all mouse clicks and key presses

* tab between bm's: takes a long time to generate chunks. increase size of chunk cache? cache increased from 30 to 60 chunks.
helps some, but they're travelling cross country, so you're always generating new chunks, so you still run out of chunks, no matter what.
forgot to add more ground meshes to go with more chunks, took a while to track that bug down.

* nokey in world and local map after spacebar press, etc, so klik doesnt play a million times.

* add klik to keypresses in process input

* shift select, world map, local map, etc - add destroy_finished_voices

* gt kangas attacked Buh-ah! wrong ai? defend ai range too big? defend AI rng cut from 50 to 30 feet.

* added nokey to end of wpn hotkeys - waits for key release, instead of clicking repeatedly.

* avians flying awfully low - switch away from wander, flock, etc, too fast? increased alt to 20 ft from 10.
increased max wander time. increased max wander range from leader. reduced chance to stop wandering at random.
reduced flock stop rng to 20 ft. added leader migrate to graze.

* learn rope making, should wear out best nearby anvil stone, not first nearby anvil stone.
added best_nearby() function: returns world object index of the highest quality object of a given type within 20 feet
of a given band member. wearout_nearby() now uses best_nearby() instead of doing a sequential search to find first nearby.

* make maintain distance and other non aggressive AI's flee when taking missile fire instead of attacking.

* cross country travel - navigation experience now has small chance to go up each minute you're in cross country travel mode,
instead of going up when you successfully arrive at your destination.

* cross country travel on rafts - navigation experience now has small chance to go up each minute you're in cross country travel
on board a raft mode, instead of going up when you successfully arrive at your destination.

* updated text on superfast screen (1-6 for gamespeed, x to stop action).

* action mode: use 1-9 for game speed. action mode and super fast screen text updated too.

* make it say "bah-gah-bah" when you start an action

* reduce chunk size to reduce chunk gen time? tested 100, 200, 300, and 400. 100 needs bigger cache, 200: no noticeable difference, 400 was slow. set it back to 300. perhaps as as big as you can generate/stream/load in a reasonable amount of time is the best terrain chunk size?

* fixed: max_ground_quads_per_chunk was set to chunksize, not (chunksize/quadsize) squared.

* in game menu: music on/off: need nobutton. added.
Norman Barrows
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
mantras were adopted for graphics:
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,
when they are already set.

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/
Norman Barrows
[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
* added "add companion" to playtest menu
* added "add lean-to" to playtest menu
* 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
* fixed: not loading and saving cm[].alive
* 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: mixotoxodon
* 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.

[color=#ff8c00]

[font=arial]Download and play it right now for free![/font]

[/color]

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




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

Norman Barrows
Adding skinned meshes to Caveman


A quick update since i haven't posted anything in a while.

I'm busy adding skinned meshes to the game.

When i started working on the game, i was not sure if i could draw the required number of skinned meshes on the target platform, so i used rigid body models to start with.

Now that i'm putting the final whammy on graphics, i decided to give skinned meshes a try.

A test run of the DX9 multianim sample showed the code could draw the required number of characters onscreen at once on the target platform.

So I turned the code from tiny.cpp into a skinned mesh library, got the dx9 animation controllers working, and figured out how to get blender and directx to work together.

You can take a look at the code here:
https://www.gamedev.net/blog/1729/entry-2261223-skinned-mesh-code-part-1-low-level-microsoft-code/

I'm able to share skeletons in blender, share animations via a batch file of copy+ commands, and the code has been designed to share meshes, textures, and materials. meshes, textures, materials, and controllers are all pooled.

The first thing i did was a test routine in the game to test the drawing of 100 characters onscreen at once with individual animations.

so far i've made all the human models and all the movement animations, and they are all up an running in the game.

i also added "change character appearance" to the playtest menu, allowing you to change a band member's appearance (even sex) at any time. This was required to assign new skinned mesh values for the band members in the long term playtest game.

attack animations are the next step. and then comes drawing weapons in hand, and equipment which is worn. i hope to simply attach all equipment to a bone, but i may need to animate some with the skeleton, the way i do for bra and loincloth. even attaching to a bone, i'll probably need a fixup transform on a per object basis to position it precisely with respect to a bone. and there are 65 kinds of weapons....

and then comes action animations.

and then comes skinned mesh animals... i'm going to be busy for a while!

actually, its going faster than anticipated. about 2 weeks to figure out dx skinned meshes. about 1 week for coding - really only about 3 days work there. another week or so to figure out blender. perhaps a week to do the meshes - there's basically just two, a male and female, 5 versions of each with different facial features and shared skeletons and animations. animations are taking about 30 minutes each on average to create, add to the game, test, and fix as needed.

i think there are only about a dozen attack animations per sex. and two to three dozen action animations. maybe a week's worth of work there.

for animals, i hope to use a few basic skeletons (such as quadruped) scaled to various body meshes, with shared animations. i think i'll be able to share animations between similarly scaled quadrupeds. so maybe one set for large quadrupeds, and one for small. each animal will only need about half a dozen animations. but there are fifty of them....

i don't plan to release a new beta until i have at least the attack and a few placeholder action animations in, as well as drawing weapons and equipment. The current demo expires soon, so there may not be a demo available for a while while i make the necessary changes.

once attack and weapons are in, i'll post a new demo, then move on to doing more action animations and skinned mesh animals.
Norman Barrows

Major changes to Caveman v3.0 since the August 2015 release of beta 21:

ENCOUNTERS: (encounters and treasure now scale to party size AND level, not just party size)
* regular and quest encounter number appearing now scales based on party strength (numbers AND combat skills), so you get tougher encounters at higher levels of experience.
* regular and quest encounter treasure quantity scales with number appearing - which is now based on party strength (not just party size).
* quest treasure quality now scales with party strength.
* time of day now affects encounter chances.
* remaining resource levels in a map square now affect encounter chances in that map square.

COMBAT:
* hit location and damage by body section, including cripppling, and its effect on combat, movement, and all actions.
* modeling of critical hits.
* modeling of bleedout, including a new "staunch wounds" action.
* check follower health and and check pet health actions (shows dmg by section, bleeding, etc).
* separate weapon hotkeys for each bandmember.
* new orders: alarm! (IE battlestations, we're under attack), stop what you're doing (stop current action).
* new action: automatically walk around and pickup ammo. super nice when you have dozens of arrows lying about after a combat.
* you can now change weapons while attacking. you just have to start the attack over with the new weapon, thats all.
* option to switch to bandmember when they get an encounter if they are not the current bandmember (IE the one the player is currently controlling).
* new skill: combat defense. works in lieu of hp increasing with level. refects you getting better at defending yourself.
* new combat move: dodge. quickly moves you fwd/back/left/right.

AI:
* new land predator AI.
* new defend location AI (used by quest encounters).
* new pack hunter AI.
* new domesticable wild animal AI (used by dire wolves).
* new follower AI
* new pet AI
* new combo defend/maintain distance AI - maintains distance from stronger animals, stands its ground and defends against others.
* respond to missile fire by animal type (all of a type attack or flee, not just the one fired upon).
* animals flee from campfires.
* graze behavior (wander, stand, flock, migrate) for pets.
* improved (but not perfect yet) AI for avians vs cliffs.


BUTCHERING ANIMALS:
* re-balanced amount of meat, hides, tendon, etc from animals. amount of meat, bone, hides, etc on an animal is now based on animal weight. all animal types now have a weight. the heaviest being Stegodon (a type of mastodon) at 28,000 lbs.
* individual tracking of meat, hide, bones etc left on a carcass (and thus available for harvesting). also tracks meat quality - and meat on carcasses spoils over time too.
* butcher actions now take a short amount of time, and yield one unit of resources, and continue until you can't carry any more or there are no more resources. it used to take a long time (like a week for a single caveman vs a mammoth carcass!), then give you everything at once.
* multiple band members can now butcher the same carcass simultaneously.

QUEST GENERATORS:
* implemented 20 of 50 planned quest generators.

NEW OBJECTS:
* teepee - basically a portable hut.
* bedroll - basically a portable version of bedding.
the teepee and bedroll combined with the travois means you can now take your entire camp with you.


ACTIONS:
* you can now build huts and lean-to's in caves.
* new dialog option: greet caveman
* new dialog option: exchange news - added in anticipation of adding fame and / or reputation to the game. exchanging news is how fame/reputation will travel.
* added ability to abandon quests you no longer wish to pursue.
* success or failure sound effects and messages for all actions upon completion

TRADE:
* re-balanced trade value of items
* traders now have limited quantities of inventory and money.

SIMULATION:
* max band members increased to 50
* max active animals increased to 500
* water stat goes down faster in hot weather.
* band members now stop most actions if their mood drops too low.
* improved domestication of dire wolves.
* local temperature now affects rate of food spoilage.
* tracking of resource depletion in a map sqaure on a per type basis, instead of as one generic resource.
* resources now replenish continually over time, instead of being totally depleted for a while before instantly replenishing to 100%.
* wild vegetables and poison plants are now found in more types of terrain.
* ability to exchange items with your travelling companions. includes tracking ownership, yours vs theirs. and NO, you can't take their stuff!
* gifts to NPCs now appear in their inventories.
* automatic transfer of liquids with containers finally works correctly.
* rafts have now been fully implemented. collision checks, AI, actions, etc - everything works with rafts now. during testing, it was very cool sailing across the ocean on a raft with one other band member, one companion, and my pet dire wolf, and seeing a new shore for the first time.
* friendly cavemen now have a chance to come up to you and initiate various dialog actions when you encounter them.

SKINNED MESHES:
* better animations
* correct materials
* correct pitch relative to the 3pv camera
* drawing of equipment

TUTORIAL:
* added making a wood spear to the tutorial - the stone knife object became a cutting tool, which is no longer a weapon.

OTHER:
* numerous minor adjustments and fixes to game balance - god is in the details!

a long period of time was spent addressing the question of "what to do when you're high level?".
the traditional solution of "Build a castle, raise an army, conquer the world!" from classic Dungeons & Dragons doesn't really work that well with a stone age setting.
turns out, its not "what to do when you're high level?", its "what to do when you've done it all?" (IE used up all the content in the game).
players need a continual supply of compelling new content appropriate for their level, not that hard in classic D&D, given an obliging DM. somewhat harder to do in video games (free high quality DLC to the rescue).
regular and quest encounters and treasure that scale to player's level provides content of appropriate difficulty for the player's level.
the ability to generate 50 different types of quests (compare to two for Skyrim's radiant quest system) will help keep things from getting repetitive too quickly.
a quest editor is also planned, along with some number of quests made with it, such as one or more optional story line campaigns. this will allow users to create and share their own quests. which may provide another possible source for compelling new content appropriate for the players level (since quest editor quests -IE number appearing, and treasure quantity and quality- will also scale automatically to player level).

WHATS NEXT:
* the ability to build a castle - caveman style. IE wood, dirt, and stone wall objects.
* multi-band settlements (proto-villages) - ask you allies to move next door.
* making the player seek out a wide variety of foods so they don't just stockpile and eat nuts all the time (for example). eating the same thing all the time will nuke your mood. maybe your stats too if mood isn't enough motivation.
* there are still a number of new actions, objects, and animal types still to be added to the game.
* misc features such as browsers for object types, animal types, and actions.
* multi-band gatherings
* mini games:
- stick and hoops (similar to lawn darts)
- chunkey (hit the thrown ball with the spear)
- non-lethal combat
- archery competitions
- and of course "rock", as in rock-paper-scissors. but its the stone age, so its before they invented paper and scissors, so they just have "rock". pretty boring game actually - always ends in a tie! .
* boss monster and boss caveman encounters for high level players.
* final graphics

and then it will finally be time to release. smile.png


there is currently no beta demo available. the public beta was a smashing success, with only two users reporting issues, one related to startup resolution detection, and the other unrelated to the game (corrupt UAC file interferes with install/launch, causing the dreaded BEX error). as a result, the startup resolution detection code has been beefed up to explicitly check caps, instead of assuming that caps which should be there are there.

I may run a semi-private beta for folks interested in providing feedback on gameplay. not sure at this point. if anyone is interested in something like that, PM me. you can never have too much feedback - whether you're talking games or guitars! . (yeah, i play the electric guitar).
.