
17 changed files with 2776 additions and 1 deletions
@ -1,2 +1,24 @@ |
|||
# galavant |
|||
# Galavant |
|||
An open world action adventure game with emergent, fully simulated AI |
|||
|
|||
Interested in working on a project with me? Galavant is a game intended to procedurally generate interesting agents and AI instead of fancy terrain. It's a big undertaking, but I feel it is the future in games. Many games have beautiful and complex worlds, but very, very few have interesting inhabitants. |
|||
|
|||
With my current design, agents are based on Maslow's hierarchy of needs. This makes it quite easy to have diverse behaviours and emergent results - for example, if you build a wall around a town full of people and burn their crops, they will eventually start starving and might even resort to cannibalism! |
|||
|
|||
Galavant is basically [Horizon](http://github.com/makuto/horizon) v2. I coded myself into a bit of a quagmire in Horizon, so I decided I would be more productive if I started over. |
|||
|
|||
Interested? |
|||
------------ |
|||
Message me on Github or email me at macoymadson@gmail.com for any questions. I'd love some help! |
|||
|
|||
There is a lot to the design of Galavant that does not fit in this readme. If you email me, I can fill you in on my goals with Galavant and what the game will actually be like. |
|||
|
|||
License |
|||
-------- |
|||
The code is MIT licensed. I intend on keeping all data (images, sprites, gameplay/design data) private, following the Doom/Quake model. |
|||
|
|||
Technical |
|||
---------- |
|||
I am writing Galavant in C++ (C++11, to be specific). I rely on SFML2 for sound, graphics, input, and networking. SFML is wrapped in my personal game library, [Base2.0](https://github.com/makuto/base2.0) (also MIT licensed), which also has other useful game-agnostic code. |
|||
|
|||
Horizon used a makefile for its build process (which I hand wrote). I have decided to abandon this method because I think it wasted a lot of my time updating it. I plan on using Codeblocks with GCC to make this process more automatic. It should also make compiling on Windows much simpler. |
|||
|
@ -0,0 +1,7 @@ |
|||
------------------ |
|||
GameData |
|||
------------------ |
|||
|
|||
gamedata stores all the data needed to play Galavant. |
|||
|
|||
If I ever choose to make Galavant a commercial product, gamedata will cease to be updated. At that point, I will sell licenses for up-to-date gamedata. For now, gamedata will contain the most up-to-date data. |
@ -0,0 +1,8 @@ |
|||
#include <iostream> |
|||
#include "objectComponent/Component.hpp" |
|||
|
|||
int main() |
|||
{ |
|||
std::cout << "Galavant\n"; |
|||
return 1; |
|||
} |
@ -0,0 +1,21 @@ |
|||
#ifndef COMPONENT_CPP |
|||
#define COMPONENT_CPP |
|||
|
|||
#include "Component.hpp" |
|||
#include "ObjectType.hpp" |
|||
#include "Object.hpp" |
|||
|
|||
ComponentType Component::getType() |
|||
{ |
|||
return type; |
|||
} |
|||
ObjectType Component::getOwnerType() |
|||
{ |
|||
return ownerType; |
|||
} |
|||
ObjectID Component::getOwnerID() |
|||
{ |
|||
return ownerID; |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,63 @@ |
|||
#ifndef COMPONENT_HPP |
|||
#define COMPONENT_HPP |
|||
|
|||
#include "ObjectID.hpp" |
|||
#include "ObjectType.hpp" |
|||
|
|||
enum ComponentType; |
|||
struct ComponentUpdateParams; |
|||
class Object; |
|||
|
|||
/* --Component--
|
|||
* Components are modular bits of logic and data designed to work with other |
|||
* modular components. Objects are collections of components. Component is an abstract |
|||
* class. |
|||
*/ |
|||
class Component |
|||
{ |
|||
public: |
|||
// Note that the constructor and destructor shouldn't have to be executed
|
|||
// every time a Component is created. Initialize and Deinitalize should do everything
|
|||
// necessary for a component to be reused
|
|||
virtual ~Component(); |
|||
|
|||
// Getters for types
|
|||
ComponentType getType(); |
|||
ObjectType getOwnerType(); |
|||
ObjectID getOwnerID(); |
|||
|
|||
// Initialize the component. Components should be able to be reused after initialize is called.
|
|||
// Components should store their parent object's address for later use
|
|||
// Return false if initialization failed for any reason, and the object creation will
|
|||
// be aborted
|
|||
virtual bool initialize(Object* parentObject); |
|||
|
|||
// Once all sibling components in an object have been initialize, postInitialize is executed.
|
|||
// Use this function to find all sibling components that your component is dependent on, as well
|
|||
// as any component-component initialization communication that might need to happen.
|
|||
virtual bool postInitialize(); |
|||
|
|||
// The parent Object has been scheduled to be destroyed. preDestroy() is called on every component
|
|||
// before components are actually destroyed. This is the "last supper" for components. Use
|
|||
// this time to do any component-component destruction communication
|
|||
virtual void preDestroy(); |
|||
|
|||
// The parent Object is being destroyed. Perform any destruction necessary here. It is up to
|
|||
// you to decide what is destroyed in destroy() and what is cleared in initialize().
|
|||
virtual void destroy(); |
|||
|
|||
// Perform all logic for your component here
|
|||
virtual void update(ComponentUpdateParams& updateParams); |
|||
|
|||
// TODO: Component save and load functions
|
|||
//virtual bool save(SaveBuffer *saveBuffer);
|
|||
//virtual bool load(LoadBuffer *loadBuffer);
|
|||
|
|||
protected: |
|||
private: |
|||
ComponentType type; |
|||
ObjectType ownerType; |
|||
ObjectID ownerID; |
|||
}; |
|||
|
|||
#endif // COMPONENT_HPP
|
@ -0,0 +1,10 @@ |
|||
#ifndef COMPONENTTYPES_HPP |
|||
#define COMPONENTTYPES_HPP |
|||
|
|||
enum class ComponentType : int |
|||
{ |
|||
NONE = 0, |
|||
TEST |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,87 @@ |
|||
#ifndef OBJECT_CPP |
|||
#define OBJECT_CPP |
|||
|
|||
#include "Object.hpp" |
|||
#include "Component.hpp" |
|||
|
|||
const int COMPONENTHANDLE_NULL = -1; |
|||
|
|||
|
|||
Object::Object() |
|||
{ |
|||
shouldDestroy = false; |
|||
numActiveComponents = 0; |
|||
id = OBJECT_ID_NONE; |
|||
type = nullptr; |
|||
} |
|||
Object::~Object() |
|||
{ |
|||
|
|||
} |
|||
|
|||
// Provides a layer of abstraction around the internal storage of Component pointers
|
|||
Component* Object::getComponentAtIndex(int i) |
|||
{ |
|||
if (i >= 0 && i < numActiveComponents) |
|||
return components[i]; |
|||
return nullptr; |
|||
} |
|||
|
|||
// Searches through components this object is composed of for one of
|
|||
// the provided type. Returns a handle
|
|||
// Returns a ComponentHandle which can be used to get a pointer to
|
|||
// a component of the requested type.
|
|||
Object::ComponentHandle Object::getComponentHandleForType(ComponentType componentType) |
|||
{ |
|||
for (int i = 0; i < numActiveComponents; i++) |
|||
{ |
|||
Component* currentComponent = getComponentAtIndex(i); |
|||
|
|||
if (currentComponent) |
|||
{ |
|||
if (currentComponent->getType() == componentType) |
|||
return i; |
|||
} |
|||
} |
|||
|
|||
return COMPONENTHANDLE_NULL; |
|||
} |
|||
|
|||
// Returns true if the ComponentHandle is valid, and points to a valid
|
|||
// Component.
|
|||
bool Object::isValidComponentHandle(ComponentHandle componentHandle) |
|||
{ |
|||
if (componentHandle == Object::COMPONENTHANDLE_NULL |
|||
|| componentHandle >= numActiveComponents) |
|||
return false; |
|||
return true; |
|||
} |
|||
|
|||
// Returns a pointer to the component indicated by the handle.
|
|||
// This pointer should NOT be stored on the heap! Components can
|
|||
// move around in memory, so storing direct pointers is not ok!
|
|||
Component* Object::getComponent(Object::ComponentHandle componentHandle) |
|||
{ |
|||
if (isValidComponentHandle(componentHandle)) |
|||
return getComponentAtIndex(componentHandle); |
|||
return nullptr; |
|||
} |
|||
|
|||
// Returns the value of shouldDestroy. If true, whatever is managing
|
|||
// the object should notify all components of the impending destruction,
|
|||
// destroy the components, then destroy the object
|
|||
bool Object::shouldDestroyObject() |
|||
{ |
|||
return shouldDestroy; |
|||
} |
|||
|
|||
// Sets the value of shouldDestroy to true. Once set, it cannot be
|
|||
// undone. The actual destruction should be handled by the object's
|
|||
// manager after checking shouldDestroyObject()
|
|||
// This function is meant to be used by the object's components to self-destruct
|
|||
// Destruction will not happen immediately - it is up to the object's manager
|
|||
void Object::requestObjectDestruction() |
|||
{ |
|||
shouldDestroy = true; |
|||
} |
|||
#endif |
@ -0,0 +1,85 @@ |
|||
#ifndef OBJECT_HPP |
|||
#define OBJECT_HPP |
|||
|
|||
#include "ObjectID.hpp" |
|||
#include "ObjectType.hpp" |
|||
#include "ComponentTypes.hpp" |
|||
|
|||
/* --Object--
|
|||
* Objects hold a collection of Components. Object provides an abstraction |
|||
* layer for Components so that components can be moved in memory without |
|||
* affecting other Components. |
|||
* |
|||
* Note that Objects cannot hold more than one Component of the same type. |
|||
* If this is required for some reason, you should redesign the system, or |
|||
* make the component support it internally |
|||
*/ |
|||
class Component; |
|||
struct ObjectType; |
|||
class Object |
|||
{ |
|||
public: |
|||
Object(); |
|||
~Object(); |
|||
|
|||
// A handle to a Component this Object has
|
|||
// Components (and all other external users of an Object's components) should
|
|||
// NEVER store pointers to an Object's components on anything other than
|
|||
// the stack. ComponentHandles, however, are safe to store. This is so
|
|||
// that Components can be moved around in memory without breaking references
|
|||
typedef int ComponentHandle; |
|||
|
|||
// Searches through components this object is composed of for one of
|
|||
// the provided type.
|
|||
// Returns a ComponentHandle which can be used to get a pointer to
|
|||
// a component of the requested type.
|
|||
// Note that Objects can only have one Component of the same type
|
|||
// Check your ComponentHandle's validity with isValidComponentHandle()
|
|||
ComponentHandle getComponentHandleForType(ComponentType componentType); |
|||
|
|||
// Returns true if the ComponentHandle is valid, and points to a valid
|
|||
// Component.
|
|||
bool isValidComponentHandle(ComponentHandle componentHandle); |
|||
|
|||
// Returns a pointer to the component indicated by the handle.
|
|||
// This pointer should NOT be stored on the heap! Components can
|
|||
// move around in memory, so storing direct pointers is not ok!
|
|||
// Note that getComponent() checks the validity of the ComponentHandle
|
|||
// Returns nullptr if the Handle is invalid
|
|||
Component* getComponent(ComponentHandle componentHandle); |
|||
|
|||
// Returns the value of shouldDestroy. If true, whatever is managing
|
|||
// the object should notify all components of the impending destruction,
|
|||
// destroy the components, then destroy the object
|
|||
bool shouldDestroyObject(); |
|||
|
|||
// Sets the value of shouldDestroy to true. Once set, it cannot be
|
|||
// undone. The actual destruction should be handled by the object's
|
|||
// manager after checking shouldDestroyObject()
|
|||
// This function is meant to be used by the object's components to self-destruct
|
|||
// Destruction will not happen immediately - it is up to the object's manager
|
|||
void requestObjectDestruction(); |
|||
|
|||
private: |
|||
// A list of pointers to Components the Object currently has (up to numActiveComponents)
|
|||
// OBJECT_MAX_COMPONENTS is defined in ObjectType.hpp
|
|||
Component* components[OBJECT_MAX_COMPONENTS]; |
|||
int numActiveComponents; |
|||
|
|||
ObjectType* type; |
|||
ObjectID id; |
|||
|
|||
// shouldDestroy indicates whether or not the Object should be
|
|||
// destroyed. This is meant to be used by Components to self-destruct.
|
|||
// shouldDestroy should be checked by whatever is managing
|
|||
// the object after the object's components have been updated
|
|||
bool shouldDestroy; |
|||
|
|||
// The NULL value for ComponentHandles
|
|||
static const int COMPONENTHANDLE_NULL = -1; |
|||
|
|||
// Provides a layer of abstraction around the internal storage of Component pointers
|
|||
Component* getComponentAtIndex(int i); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,16 @@ |
|||
#ifndef OBJECTID_CPP |
|||
#define OBJECTID_CPP |
|||
|
|||
#include "ObjectID.hpp" |
|||
|
|||
// The Object hasn't been assigned an ID
|
|||
const ObjectID OBJECT_ID_NONE = -1; |
|||
|
|||
// The last possible ID that can be assigned
|
|||
// TODO: Set to a better value (this was completely arbitrary)
|
|||
const ObjectID OBJECT_ID_MAX = 1000000; |
|||
|
|||
// Start assigning IDs at this value
|
|||
const ObjectID OBJECT_ID_FIRST = 1; |
|||
|
|||
#endif |
@ -0,0 +1,15 @@ |
|||
#ifndef OBJECTID_HPP |
|||
#define OBJECTID_HPP |
|||
|
|||
typedef int ObjectID; |
|||
|
|||
// The Object hasn't been assigned an ID
|
|||
extern const ObjectID OBJECT_ID_NONE; |
|||
|
|||
// The last possible ID that can be assigned
|
|||
extern const ObjectID OBJECT_ID_MAX; |
|||
|
|||
// Start assigning IDs at this value
|
|||
extern const ObjectID OBJECT_ID_FIRST; |
|||
|
|||
#endif |
@ -0,0 +1,5 @@ |
|||
#ifndef OBJECTTYPE_CPP |
|||
#define OBJECTTYPE_CPP |
|||
|
|||
|
|||
#endif |
@ -0,0 +1,17 @@ |
|||
#ifndef OBJECTTYPE_HPP |
|||
#define OBJECTTYPE_HPP |
|||
|
|||
#include "ComponentTypes.hpp" |
|||
|
|||
#define OBJECT_MAX_COMPONENTS 10 |
|||
|
|||
struct ObjectType |
|||
{ |
|||
// An array of ComponentTypes that this ObjectType requires
|
|||
ComponentType components[OBJECT_MAX_COMPONENTS]; |
|||
|
|||
// The number of Components this Object will actually use
|
|||
int totalUsedComponents; |
|||
}; |
|||
|
|||
#endif |
File diff suppressed because it is too large
@ -0,0 +1,6 @@ |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<results> |
|||
<error file="../../objectComponent/Component.hpp" line="16" id="noConstructor" severity="style" msg="The class 'Component' does not have a constructor although it has private member variables. Member variables of builtin types are left uninitialized when the class is instanciated. That may cause bugs or undefined behavior." /> |
|||
<error file="../../objectComponent/Object.hpp" line="19" id="noConstructor" severity="style" msg="The class 'Object' does not have a constructor although it has private member variables. Member variables of builtin types are left uninitialized when the class is instanciated. That may cause bugs or undefined behavior." /> |
|||
<error file="../../objectComponent/ObjectType.hpp" line="10" id="unusedStructMember" severity="style" msg="struct or union member 'ObjectType::components' is never used." /> |
|||
</results> |
@ -0,0 +1,55 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
|||
<CodeBlocks_project_file> |
|||
<FileVersion major="1" minor="6" /> |
|||
<Project> |
|||
<Option title="galavantCodeblocks" /> |
|||
<Option pch_mode="2" /> |
|||
<Option compiler="gcc" /> |
|||
<Build> |
|||
<Target title="Debug"> |
|||
<Option output="bin/Debug/galavantCodeblocks" prefix_auto="1" extension_auto="1" /> |
|||
<Option object_output="obj/Debug/" /> |
|||
<Option type="1" /> |
|||
<Option compiler="gcc" /> |
|||
<Compiler> |
|||
<Add option="-g" /> |
|||
<Add directory="objectComponent" /> |
|||
</Compiler> |
|||
</Target> |
|||
<Target title="Release"> |
|||
<Option output="bin/Release/galavantCodeblocks" prefix_auto="1" extension_auto="1" /> |
|||
<Option object_output="obj/Release/" /> |
|||
<Option type="1" /> |
|||
<Option compiler="gcc" /> |
|||
<Compiler> |
|||
<Add option="-O2" /> |
|||
<Add directory="objectComponent" /> |
|||
</Compiler> |
|||
<Linker> |
|||
<Add option="-s" /> |
|||
</Linker> |
|||
</Target> |
|||
</Build> |
|||
<Compiler> |
|||
<Add option="-Weffc++" /> |
|||
<Add option="-pedantic-errors" /> |
|||
<Add option="-pedantic" /> |
|||
<Add option="-std=c++11" /> |
|||
<Add option="-Wall" /> |
|||
<Add option="-fexceptions" /> |
|||
</Compiler> |
|||
<Unit filename="../../main.cpp" /> |
|||
<Unit filename="../../objectComponent/Component.cpp" /> |
|||
<Unit filename="../../objectComponent/Component.hpp" /> |
|||
<Unit filename="../../objectComponent/ComponentTypes.hpp" /> |
|||
<Unit filename="../../objectComponent/Object.cpp" /> |
|||
<Unit filename="../../objectComponent/Object.hpp" /> |
|||
<Unit filename="../../objectComponent/ObjectID.hpp" /> |
|||
<Unit filename="../../objectComponent/ObjectType.cpp" /> |
|||
<Unit filename="../../objectComponent/ObjectType.hpp" /> |
|||
<Extensions> |
|||
<code_completion /> |
|||
<debugger /> |
|||
</Extensions> |
|||
</Project> |
|||
</CodeBlocks_project_file> |
@ -0,0 +1,35 @@ |
|||
# depslib dependency file v1.0 |
|||
1445721187 source:/home/macoy/devCollab/galavant/src/main.cpp |
|||
<iostream> |
|||
"objectComponent/Component.hpp" |
|||
|
|||
1447565212 /home/macoy/devCollab/galavant/src/objectComponent/Component.hpp |
|||
"ObjectID.hpp" |
|||
"ObjectType.hpp" |
|||
|
|||
1447564622 /home/macoy/devCollab/galavant/src/objectComponent/ObjectID.hpp |
|||
|
|||
1447563871 /home/macoy/devCollab/galavant/src/objectComponent/ObjectType.hpp |
|||
"ComponentTypes.hpp" |
|||
|
|||
1445722684 /home/macoy/devCollab/galavant/src/objectComponent/ComponentTypes.hpp |
|||
|
|||
1447562600 source:/home/macoy/devCollab/galavant/src/objectComponent/Component.cpp |
|||
"Component.hpp" |
|||
"ObjectType.hpp" |
|||
"Object.hpp" |
|||
|
|||
1447565426 /home/macoy/devCollab/galavant/src/objectComponent/Object.hpp |
|||
"ObjectID.hpp" |
|||
"ObjectType.hpp" |
|||
"ComponentTypes.hpp" |
|||
|
|||
1445724601 source:/home/macoy/devCollab/galavant/src/objectComponent/ObjectType.cpp |
|||
|
|||
1447565050 source:/home/macoy/devCollab/galavant/src/objectComponent/Object.cpp |
|||
"Object.hpp" |
|||
"Component.hpp" |
|||
|
|||
1447565116 source:/home/macoy/devCollab/galavant/src/objectComponent/ObjectID.cpp |
|||
"ObjectID.hpp" |
|||
|
Loading…
Reference in new issue