Darwinian_Coding: ( Implementing Creature Cognitive Replay )

Nov. 28, 2011
Darwinian_Coding: ( Implementing Creature Cognitive Replay )

[In this reprinted #altdevblogaday-opinion piece, WhatIf Productions' Jake Kolb explains "Creature Cognitive Replay", and examines what approaches work best when implementing it in video games.] Context: where we use this "Creature Cognitive Replay" covers how we code video-game entities, such as Space-Marines or Martian-Primates, to learn and store 'knowledge', such as "where are my favorite forest hiding places", "is that large blinking-red object blocking my path dangerous?", or "how do i rebuild my destroyed wigwam" Creating a believable, living world requires us to separate the omniscient simulation or 'game' knowledge from what an individual creature should be able to know, such as the difference between castle guards automatically knowing the player's position versus seeing/hearing an object move and having to investigate what the sound might be. While every game's needs are quite different, the focus here is what approaches have worked best simulating 100s to 10,000s of unique creatures in a reasonably balanced ecosystem of producers (plants) and consumers (herbivores & carnivores). The last three approaches we used were given between 8 & 64 MiB of active 'current-time' creature-knowledge-memory for PC desktop applications but could easily move to mobile or console spaces. The 'replay' part of the title handles timeline based thinking so we can 'rewind/fast-forward' our simulation and the knowledge will be accurate/consistent. In this discussion, we use 'knowledge' as a unit of information and a 'thought' as a piece of knowledge accessible to an entity which can change over time. Goals: what we need

  • Speedy Queries: entities can ask questions about their knowledge to make decisions (Note: 'decisions' are made using an interpreted script or pre-coded behaviors).

  • Instancing & Breeding: supports 'generic' abstractions such as 'space-tiger' vs specific tigers and allows cloning, breeding, and other ways to mix any inherited knowledge when they are created at runtime.

  • Trending: can store the expected/default/popular thoughts (everybody knows that SpaceCola increases your speed) vs fringe/unique thoughts (SpaceCola decreases my health).

  • Trust: supports 'certainty' to help decide how reliable the knowledge is to the entity.

  • Origin: stores knowledge from different sources, such as instinct vs communicated vs sensory vs analytical thought-process.

  • Rewind: handles recording/playback of each creature's knowledge over time to permit simulation rewind and cognitive replay.

Solutions: how we tried Technique: Straightforward-Object-Oriented Programming ( SOOP )

Our first attempt at representing "knowledge per entity" used classic Smalltalk/C++ object-oriented programming with a hierarchy of 'classes of knowledge' and a vast virtual-function interface to communicate with each class. Templates were not supported back when we tried this approach and we had a huge base of files to handle any interactions with the knowledge and ownership-access. We had to anticipate any possible query an entity might want to make ahead of time to match the entity type (Gorilla) with the member functions of the knowledge types ( Mammal, Physical, Jungle_Prowler, Nest_Builder ) and the permutations quickly got out of hand. Pros: Easy to code & debug using a design doc for each type of entity. Given fixed entity behaviors, little to no design changes when coding, and few iterations of tweaking the behavior code, this is a safe, reliable choice. Easy to rewind/fast-forward given fixed structures of the SOOP approach as we can just difference the bits between two structures and run-length/huffman-encode those deltas. Cons: Creating new queries required new code which was expensive in time and couldn't be done by a designer. Given the classes were fixed at runtime, we could not create new knowledge-classes or modify their member types in real-time. Using over 600 knowledge-class files took a long time to compile and made a ginormous executable. Given the number of classes involved to instantiate most entities, such as dog or cat or space-tank, it also took a while to create and destroy creatures, which did not scale well to large numbers. While a straightforward OOP is an appealing approach to begin with, maintaining/evolving the code was not well suited to the real-world development demands of sudden/frequent design changes and complex iterations of tweaking behaviors. After missing two milestones, we reworked our schedule to switch to the TAM approach below.

Technique: Tuple-Arranged-Minds ( TAM )

Inspired by the admirable and rich AI legacy of functional languages like LISP, Prolog, & Scheme, we decided to implement something similar that interfaced with our existing codebase. Back then in the mid-1990′s, we simply couldn't find an 'open-source' engine to plug-in, so we gave each entity a red-black-tree of linked lists. Each 'list' node had a knowledge-type string such as enemies, goal_location, or favorite_weapon and one or more thought-strings such as 'robots, mosquitoes', 'treehouse', or 'shotgun gasgun, sonic-screwdriver'. We called these nodes a "thought-tuple" and we used it for function-style queries, such as returning 'no

Tags: 2011

JikGuard.com, a high-tech security service provider focusing on game protection and anti-cheat, is committed to helping game companies solve the problem of cheats and hacks, and providing deeply integrated encryption protection solutions for games.

Explore Features>>