Component Based Entity System Design Part 2


Finally! Part 2 has arrived. Purple Pwny is really still in a formulation state as far as development of an actual game goes, so we havn’t had a chance to extensively use the component system in anything other than a testing scenario. The only finalized portion of the ComponentManager interface thus far is the GetComponent function.

GetComponent takes the name of a component family and an optional specialization parameter that applies to said family. For instance, to retrieve a component of type HealthComponent specialized for an Elephant character one would call as follows:

1
HealthComponent *health = m_ComponentManager->GetComponent<health>("Health", "Elephant");

The ComponentManager class serves mostly to act as a factory for customized components at this time. However, I dont foresee it needing much functionality outside of that as Entities are intended to “manage” their own components.

Here is the relevant portion of the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template <typename T>
T* ComponentManager::GetComponent(std::string name,std::string specialization) {
 
    m_xmlElement = doc.FirstChildElement(name);
    m_xmlElement= m_xmlElement->FirstChildElement(specialization);
    std::map<std::string, boost::variant<int,std::string> > props;
    for ( TiXmlElement *m_xmlElementTemp = m_xmlElement->FirstChildElement(); m_xmlElementTemp; m_xmlElementTemp = m_xmlElementTemp->NextSiblingElement()) {
        int ival;
        std::string sval;
        if (m_xmlElementTemp->Attribute("intval")) {
            m_xmlElementTemp->QueryIntAttribute("intval",&ival);
            props[m_xmlElementTemp->ValueStr()] = ival;
        }
        else if (m_xmlElementTemp->Attribute("strval")) {
            m_xmlElementTemp->QueryValueAttribute("strval",&sval);
            props[m_xmlElementTemp->ValueStr()] = sval;
        }
    }
 
    T* comp = new T();
 
    comp->Set(props);
    return comp;
}
}

At the moment, this actively parses the XML with 0 caching of configurations. This allows changes to occur in real-time to newly added components, which, with little modification, leads to a variety of interesting editor/game possibilities. It’s very simple to convert the current system into a cached mapping of key/value pairs. The reason we have yet to do this however, is because the plan is to permanently cache components in a SQLite database in the very near future.

On the horizon: Caching component configurations, and a 3 part introduction to the Harmony renderer.

<3



Dear Craigslist


Purple Pwny Games was formed in 2008 by me, Tyler Bello. Originally, Purple Pwny was to serve as a platform to build my portfolio, with the eventual hope of being employed by one of the many local juggernauts. I soon came to the realization, however, that I was disgusted by the recent direction of the industry. Within the last several years, games have lost their passion, their challenge, their energy — everything that made them great. This is a case of complacency in an industry that wishes to open the market to those which it once kept out. I want to make it clear that I have no problem with this. What I do have a problem with is that this complacency has spread to all games, rather than just a specific subset of them. Take Halo for instance, one the highest selling games of all time. Halo opened the door to FPS for those who had never picked up a controller. This is fine. This is great! What’s not great is that every FPS since Halo has catered to those who have never picked up a controller. With the ludicrous budgets of modern video games, this pandering appeared to be the only way to succeed on a grand scale. Only recently have incredible indie games created by teams of 2-3 seen a resurgence in popularity as a direct result of the current state of the industry. Because of this, I decided to switch Purple Pwny’s focus from a portfolio site to a fully fledged video game company in an effort to play a part in what I believe is the next big thing in the industry.

The 4 foundational tenets of said company are to be as follows:

  • Development shall be free flow. I will provide my employees with an abstract task, and they will be given full artistic freedom to make that abstract idea happen as they see fit (this concept applies to both artists and programmers, though more loosely to programmers). I acknowledge that I am not a designer or an artist; they have the vision, and I am not one to place limits on their creativity by giving detailed tasks.
  • Professionalism, in its bastardized modern form, is not something that we will rigorously follow. One’s clothes and hair do not determine his skillset, if we are to be judged based upon these superficial things, then it is surely the loss of those who make the judgement and not our own (and perhaps my wallet, but I’m secure enough to take that risk).
  • If one works hard, one cannot fail in any sense. In Purple Pwny’s worst case scenario, the company doesn’t take off, we make shitty games, the concept is a failure, one will still have received the experience of working on a team and creating something…and that means a lot in this industry.
  • Just do it. It sucks that it’s Nike’s slogan, but it applies heavily here. How many other people, are taking their little game development team and treating it as a true company? The difference between a ‘team’ and a ‘company’, however, is quite large. A team, in this sense, carries no true connection, no penalty for leaving, and little focus on monetization (and thus little chance of it). If one just takes the plunge and ‘does it’, makes a charge for the top, there’s at least a possibility of true success whereas those who don’t shoot for the top for fear of failure, will never know if they can make it.

In an effort to make this dream a reality, I placed ads on Craigslist looking for local people to work for no pay in an upstart game company. The response was tremendous, both negatively and positively. I receieved a steady 10-20 resumes a week while the ad was active. Admittedly, my screening process is rougher than most. I need to create a dream team, a group of people who are talented, passionate, and most importantly, share my ideals. In a large company, the ideals are fairly irrelevant. Business decisions will go on regardless of what the underlings think. In what will be such a tight knit company though, any disagreements are sure to cause turmoil throughout the team, so it is best to do all that you can to keep them to a minimum.This is no short order, and as such, finding talent that meets all criteria is quite a challenge. I’ve done a trial period with several people, none have fully worked out yet. Many on Craigslist feel compelled to bash this process stating:

  • “You should change your ad. You sound like assholes.”
  • “Act professional and swallow it.”
  • “Why do you expect someone to show up and work their asses off for absolutely nothing?”
  • “They don’t care and won’t work with you because they will receive nothing in return.”

These responses convey the attitude that has taken over not just this industry, but most. The attitude of a robotic sheeple who bow to their overlords and do whatever they are told. Little do the nay-sayers know how many responses I receive weekly…from individuals that, to be honest, are far above working for free. Purple Pwny must be attracting them for a reason. Some of them have even stated that they are looking to escape the humdrum of their 9-5 cubicle job.

So, this one’s for you, trolls of Craigslist. Every negative response that I receive will now be linked to this post.

Addendum:

Damn, this struck a nerve! We’ve been getting so many hits on this post, and it looks like someone posted it up on SA (I can’t find it at this moment however). The storm of negative comments to this post shows a great misunderstanding. I don’t expect anyone to give up their day job to work here (hell, I havn’t even left MY day job!). Nor do I expect to line my pockets with gold while my employees wallow in despair. So many game companies, and tech companies in general, who do not pursue venture funding, begin in the garage with a group of unpaid friends. Unfortunately, it’s 2009 and this has grown to be a very uncommon practice. The fact remains, WE’RE NOT PROFITABLE. Who in their right mind would work here if I were rolling in money and they were getting none of it (and actually, the plan is that if we ever do become profitable…it is split evenly among all of us).



Lurking Around


sneaky_sneaky

I have been away for some time, extremely busy with school. But i have not forgotten about you guys ^-^!

I will try my best to keep you all posted on new art.



Component Based Entity System Design Part 1


About a week ago, I decided that if I needed to dynamic_cast my entities everywhere they were used, I was doing something wrong. It’s not that an inheritance based entity system is inherently wrong per se, but in large systems it tends to become an impossible to manage web of sloppy code. Seeing this issue, and wanting to make Harmony the best it can be, I began to tackle the monstrous job of refactoring the entity code to a component based design.

I read the available literature (which is sparse, as it always is with entity systems):

1. Evolve Your Hierarchy : Refactoring Game Entities With Components
2. Game Programming Gems 6 , Section 4.6 : Game Object Component System
3. A Data-Driven Game Object System
4. 301: Introduction to Dungeon Siege Architecture

and got to work.

In my opinion, the implementation in Game Programming Gems 6 is too rigid and overly complex, 2 things that I’m trying to escape in Harmony. So after struggling to wrap my head around how to get it to work, since, if it’s in a book, it MUST be the best…I gave up, recognized that ingenuity is the key to success and created an original component based entity system design.

This is part 1 of a 2 part series, in this post I will review the Component class itself aswell as the Entities that hold them.

Part 2 will cover the Component Manager.

In most games, entities are derived from a series of concrete base classes. These base classes provide the ability to render, move, posses AI, etc. This system of inheritance quickly becomes unwieldy in practice and devolves into a mass of dynamic_casts and spaghetti code. Also, this system does not lend itself well to data driven game design, as all possible entities and the interfaces that they implement must be specified at compile time. Optimally, in modern games, we want a system in which we can create entities dynamically on the fly at runtime. This not only makes the compile/debug cycle a non-issue for designers, but also opens up a realm of possibilities including: easy post-release patches that add new content through pure data, Spore-like creature creation, and simple user generated content.

An alternative to the standard architecture, which has come into the spotlight only recently, is the component based architecture. In this system, there is typically only 1 very generic Entity class that serves to hold the Components that implement its functionality. An Entity with hit-points would contain the HealthComponent, which would implement all of the methods relevant to dealing with hit points. This greatly increases the cleanliness of Entity’s direct interface and moves it all out into easy to manage and fully pluggable classes of functionality.

My implementation of this system is as follows:

Component.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Component {
 
public:
 
    Component();
    ~Component();
 
    virtual void Update() = 0;
 
    std::string GetFamily();
    std::string GetName();
 
    void    SetOwner(Entity*);
    Entity* GetOwner();
 
    virtual void Set(std::map<std::string,boost::variant<int,std::string> >) = 0;
 
protected:
    std::string m_familyName;
    std::string m_name;
    Entity* m_owner;
 
};

To create components, one must simply derive a type from this base class which implements all the base facilities that a component may need. The Set() function is used in conjunction with XML to give instance specific values to the properties of a component. For example, here is a snippet from the implementation of HealthComponent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HealthComponent::HealthComponent() {
    m_name = "BasicHealth";
    m_familyName = "Health";
    hp = 100;
    max = 100;
    min = 0 ;
}
 
  void HealthComponent::Set(std::map<std::string,boost::variant<int,std::string> > props){
   //a variant is used because data can only be one of 2 things
    hp = boost::get<int>(props["hp"]);
    max = boost::get<int>(props["max"]);
    min = boost::get<int>(props["min"]);
 
  }

HealthComponent’s members are given sensible initial values in the contructor, if one wishes to use this component with different data, one can simply define a component template in XML (shown in part 2 of this article) which will override these default values. For instance, the following template would be suitable for a tank character:

1
2
3
4
5
6
7
8
<health>
  <tank>
    <name strval="TankHealth"/>
    <hp  intval="1000"/>
    <max intval="1000"/>
    <min intval="0"/>
  </tank>
</health>

Entity.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Entity {
 
public:
 
    Entity();
    Entity(std::string name);
    ~Entity();
 
    unsigned int &GetID();
    std::string  &GetName();
 
    void Update();
 
    void AddComponent(Component*);
    void RemoveComponent(std::string);
 
    template<typename T>
    T * GetComponent(std::string familyName) {
        return dynamic_cast<t*>(m_components[familyName]);
    }
 
    void Do(std::string);
 
    SDL_Rect &GetLocation();
 
    unsigned int m_id;
    std::string m_name;
    static unsigned int nextID;
    SDL_Rect m_location;
    std::map<int,std::string> m_keymap;
    std::map<char,std::string> m_mousemap;
    std::map<std::string, Component*> m_components;
 
};

As you can see, an entity is little more than a container of components. In addition to components, it holds a name and position. Also, all entities are inherently able to accept input, so that is the source of m_keymap, m_mousemap, and Do(std::string). Components are held in m_components and are indexed by their family name. GetComponent(std::string) is a templated function that returns a properly pre-casted component of the family name.

Do note that the system in its current form is very bare bones, entirely lacks error checking, and is subject to sweeping changes. Stay tuned for part 2, and as always <3.



Input, the Harmony Way


Hey, Tony here. It’s been quite a while since I joined up as a programmer at Pwny (6 weeks~), however I’ve been lurking in the shadows. Well, I have emerged today to talk to you about (as the title suggests) the way in which the Harmony engine handles input. The basic idea for our input system is to create a logical way for people to adjust controls without actually having to edit and compile for every minor change. In other words, avoid putting an army of if statements inside the source code. How does one accomplish such a feat? XML. By storing different ‘keymaps’ (both mouse and keyboard control configurations) inside an XML document, the assignment of input to entities becomes trivial. One line: AddInput(Entity*,std::string keymap). Even better, the XML is formatted very simplistically, allowing for anyone to create their own keymap with ease. I can rant about how easy it is, but in the end, code speaks much louder.

Keymap.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <entity>
    <keyboard>
      <a act="MoveLeft"/>
      <d act="MoveRight"/>
      <s act="MoveDown"/>
      <w act="MoveUp"/>
    </keyboard>
    <mouse>
      <l act="MoveLeft"/>
      <r act="MoveRight"/>
      <m act="MoveDown"/>
      <y act="Vert"/>
    </mouse>
  </entity>
 
  <entity2>
    <keyboard>
      <j act="MoveLeft"/>
      <l act="MoveRight"/>
      <k act="MoveDown"/>
      <i act="MoveUp"/>
    </keyboard>
    <mouse>
      <l act="MoveLeft"/>
      <r act="MoveRight"/>
      <m act="MoveDown"/>
      <x act="Hor"/>
    </mouse>
  </entity2>

InputManager.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class InputManager {
 
public:
 
    InputManager();
    ~InputManager();
 
    void AddInput(Entity*,std::string);
    void HandleInput(SDL_Event*);
 
private:
 
    Uint8 *kbarray;
    Uint8 MouseState;
    TiXmlDocument  m_doc;
    std::vector ControllableObjects;
};

HandleInput sends messages to all objects that care about a particular event. I.e. if the event is that the ‘H’ key was pressed, only objects with a mapped ‘H’ key will receive word of the event. AddInput loops through the XML and fills the keymap with keys and their associated actions, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void InputManager::AddInput(Entity* ent,std::string keymap) {
    ControllableObjects.push_back(ent);
 
    std::string act;
    std::string key;
 
    for (TiXmlElement *m_xmlElementTemp = m_doc.FirstChildElement(keymap)->FirstChildElement("Keyboard")->FirstChildElement(); m_xmlElementTemp; m_xmlElementTemp = m_xmlElementTemp->NextSiblingElement() ) {
        m_xmlElementTemp->QueryValueAttribute("act",&act);
        key = m_xmlElementTemp->ValueStr();
        ent->m_keymap.insert(make_pair((int)key[0],act));
    }
    if (m_doc.FirstChildElement(keymap)->FirstChildElement("Mouse")) {
        for (TiXmlElement *m_xmlElementTemp = m_doc.FirstChildElement(keymap)->FirstChildElement("Mouse")->FirstChildElement(); m_xmlElementTemp; m_xmlElementTemp = m_xmlElementTemp->NextSiblingElement() ) {
            m_xmlElementTemp->QueryValueAttribute("act",&act);
            key = m_xmlElementTemp->ValueStr();
            ent->m_mousemap.insert(make_pair(key[0],act));
        }
    }
}

Scarily long arrow chains? Yes, I know.

I learned 2 invaluable rules in making this system, and will pass them on to you so that my mistakes are not duplicated:

1.) Basic rule of life: Know what you’re working with well. Seriously. Saves lives. In other words, don’t end up writing numerous lines of code attempting to do something and then figure out that something built in does it, but better. Case in point, don’t write code that polls the current state of the keyboard if your libraries do it for you.

2.) If using SDL, use GetKeyState/GetMouseState, honestly. SDL has easier to use facilities for polling events, but I have found them far inferior to SDL’s direct hardware state queries.

Good Day.



Teaser ;]


beta-level1



Hello World. This Is Your Captain, Alex, Speaking


Hello world,
My name is Alex Loeffler and I am the artist for Purple Pwny. I’m going to fill you in on what i’ll be working on for the next few weeks until the release of our first game. To start, I will be taking ideas such as genre, environment, character, and various movable objects into consideration and coming up with scenarios that provide interesting and fun gameplay. Some of you are thinking, what!?!? How can you combine such general ideas into one giant cluster? Well my simple answer for you is storyboarding. Heh who is this guy… Starting off with storyboarding? Yeah Yeah I know… it might seem weird to start off with a storyboard with no background ideas. But I feel if I pump out ideas and sketch the character, environment, and possible game elements into one piece, it helps the discovery of new concepts, genres, and game elements. Often I will use a sharpie or charcoal to sketch because they are permanent and hard to erase. You should never erase your artwork, there is always time to refine it later. An example of the method I use as follows: Say I draw a warrior princess in a swamp who has to escape the clutches of a dark wizard while avoiding poisonous shrubbery. Then, I draw a mech robot collecting wreckage from a destroyed ship while being attacked by alien savages. Ill then combine these to ideas by picking out the strongest elements of each. The product would be something like: A warrior princess collecting valuable plants from wreckage while avoiding savages. The more time I spend on this, the more fun and original concepts I can provide to you :) .
I just got back from GDC.

Made a ton of valuable contacts, and, made this to show you what I mean about combining general ideas into something worthwhile: CharacterDesign1



Implementing Camera Behaviors


A necessary addendum to the prior post on implementing a camera in SDL is the inclusion of a set of ‘behaviors’ for the camera to follow.

I’ve slightly reworked the interface to reflect how I would like the Camera to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
#include <vector>
#include "SDL.h"
 
class Entity;
 
class Camera{
 public:
  Camera(int x,int y, int width, int height);
  ~Camera();
 
  void MoveRelative(int x,int y);
  void SetPosition(int x, int y);
  void SetFollow(Entity*);
  void UnsetFollow();
  SDL_Rect GetPosition();
  void Update();
  SDL_Rect& GetViewport();
 private:
 
  void EdgePushBehavior();
 
 
  Entity * entToFollow;
  SDL_Rect m_viewport;
 
};

The new bits to note are, entToFollow, Update(), SetFollow(Entity*), UnsetFollow(), and EdgePushBehavior(). entToFollow is the entity that the camera will be basing its behavior off of, such as following the entity around the screen centered, trailing the entity, etc. Update will alter the position of the camera based upon whichever behavior is chosen. At the moment, this looks like:

1
2
3
4
5
6
void Camera::Update(){
  //implement various behaviors that a camera can have, trail, center, bob, etc
  if(entToFollow){
  EdgePushBehavior();
  }
}

If we’ve been told to base our behavior off of an entity (entToFollow has been set with SetFollow(Entity*)), perform the active behavior. At the moment, the ‘active behavior’ is hardcoded, but a SetActiveBehavior function is easy enough to implement. EdgePushBehavior() itself looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
void Camera::EdgePushBehavior(){
  //If we're hitting the right edge of the viewport
  if((entToFollow->m_location.x+entToFollow->m_location.w)>=(m_viewport.x+m_viewport.w)){
    m_viewport.x += 1; //TODO: RATE LIMITER
     }
  //left edge
  if(entToFollow->m_location.x<=m_viewport.x){
    m_viewport.x -= 1;
  }
  //top edge
  if(entToFollow->m_location.y<=m_viewport.y){
    m_viewport.y -=1;
  }
  //bottom edge
  if((entToFollow->m_location.y+entToFollow->m_location.h)>=(m_viewport.y+m_viewport.h)){
    m_viewport.y +=1;
}
}

When we hit an edge of the screen, we move the camera in the direction of travel, think Mario games. Harmony will include the most common behaviors, but adding more will be as simple as adding a new function to a derived camera class. Also in the works, is CameraManager. This will provide one point of access to all active cameras and make the management of multiple cameras trivial.



PHP Script To Add Licenses (Or Any Text) To The Beginning Of Source Files


Deciding on an open source license can be quite confusing. I chose to license Harmony with Zlib and I would say that it’s largely due to its ease of use. The documentation on open source licensing is sparse at best, and when present, overly verbose (see: GPL). Anyway, part of open source licensing is adding the license inside of comment tags at the top of every source file. Doing this manually would be tedious and uninteresting, so I flexed my PHP muscle and came up with a script to do it for me!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
 
$YEAR = 2009;
$COPYRIGHT_HOLDERS = 'Tyler Bello (www.purplepwny.com)';
 
$license = "/*
Copyright (c) $YEAR $COPYRIGHT_HOLDERS
 
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
 
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
 
    1. The origin of this software must not be misrepresented; you must not
    claim that you wrote the original software. If you use this software
    in a product, an acknowledgment in the product documentation would be
    appreciated but is not required.
 
    2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.
 
    3. This notice may not be removed or altered from any source
    distribution.
*/\n";
 
 
$directory = opendir('.');
 
print "Adding license to the following files : \n\n";
 
while(false !== ($file = readdir($directory))){
 
  if(preg_match("/.\.[cChH](pp)?/","./$file")){ //change regex to suit your particular language, this one is C/C++
    print "$file\n";
    $existingContent = file_get_contents("./$file");
    $fileHandle = fopen("$file",w);
    fwrite($fileHandle,"$license$existingContent");
    fclose($fileHandle);
 
  }}
 
closedir($directory);
 
 
?>

To use: Replace the necessary variables (Year, Copyright Holders, License) with those of your choosing. Save the file as add_license.php in the directory that contains the files you wish to license. Run it from the command line with:

1
php add_license.php

PHP isn’t the most practical way to accomplish this. Perhaps I, or another kind soul, will port it to an executable! It’s 3 AM and I can’t sleep. Awesome :D <3



How To Stall And Be Forgiven, And How To Make A Camera In SDL


Yeah, I said it would be out by Monday. Forgive me, we ran into some road blocks. Alex, our artist, is actually at GDC right now, handing out some of these. Business Cards He’s got a post for you about effective storyboarding, but he’s waiting to post it until he gets back. Tony has been out of the game due to some surprise school work, so I’ve been alone. My hands have not been idle though. I worked on creating a Camera class for the engine over the past few days. It’s actually a lot simpler than I had anticipated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
//Camera simply holds information, is not a surface that we render to.
//Check objects on rendering pass for falling within viewport. If they do,
//render them to the screen.
#include <vector>
#include "SDL.h"
 
class Entity;
 
class Camera{
 public:
  Camera(int x,int y, int width, int height);
  ~Camera();
 
  void MoveRelative(int x,int y);
  void SetPosition(int x, int y);
  SDL_Rect GetPosition(); //should return a Vec2D
  void Follow(Entity*);
  SDL_Rect& GetViewport();
 private:
 
  SDL_Rect m_viewport;
 
};

The comment at the top is fairly self explanatory. Camera is really nothing more than a way to represent a rectangular viewport used to determine the screen locations of entities. To determine the screen location we subtract the camera location from the world location of the entity. As shown here:

1
2
3
4
5
6
7
SDL_Rect* EntityManager::GetScreenLocation(SDL_Rect* loc){
 
  SDL_Rect viewport = game->m_Camera->GetViewport();
  screenPos.x = loc->x - viewport.x;
  screenPos.y = loc->y - viewport.y;
  return &screenPos;
}

And once we’ve determined the screen location, we can go 1 step further and cull entities that are no longer visible.

1
2
3
4
5
6
7
8
9
10
bool EntityManager::CullEntity(SDL_Rect& screenPos){
  //TODO:Check all points of an object to avoid pop in
 
    if(screenPos.x > SCREEN_WIDTH || screenPos.y > SCREEN_HEIGHT){
         return true; //do cull the entity
  }
 
  return false;
 
}

The only problem with this function as it stands is that there will be pop in of entities when they are moving from left to right into screen space. This isn’t too big of a deal, but will be fixed soon. To use these functions, simply blit like so:

1
2
3
if(!CullEntity(GetScreenLocation(loc))){
	SDL_BlitSurface( srcSurface, srcRect, destSurface, screenPos );
}

For the sake of clarity, these 2 functions (CullEntity and GetScreenLocation) have been left seperate, in a working environment it may be better to simply call GetScreenLocation inside of CullEntity. Coming soon, “Soft Programming vs. Hard Programming” and “Input, the Harmony Way”. Until then, <3