• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.


  • Content count

  • Joined

  • Last visited

Community Reputation

193 Neutral

About ObsidianBlk

  • Rank

Personal Information

  • Location
  1. I can't speak for AAA developers. Nor, really, indie devs. I'm just a hobbiest at the moment, but... limiting your engine/game because of "known specs" of the system you're running on, still feels silly and short sighted to me. Why cater when, if developing to be resolution agnostic, you cater to everyone! Not only would that allow your game to be as "future proof" as possible (lets say if XBox One or PS4 goes through a revision and gets a slight boost somewhere), but allow for the game/engine to migrate to platforms which support wildly different or varying resolutions with the minimum of effort.   Really... if this is being done already, why is there such a question as to whether 4k is worth it (from a development standpoint). The games should be written without resolution assumptions at all and the question of "if 4K worth it" should be left purely in the hands of people deciding whether they want to buy one.   As to the question on whether 4K is worth it from a financial standpoint... my opinion is no. I make a pretty decent salary at the moment and a financial purchase of $400+ is a big decision for me. At the current price point of 4K TVs, they're definitely not worth it. If I could nab a 30" or 40" 4k at about $400, then, maybe.
  2. What I'm about to say is one of those "easier said than done" sort of things, but it's an ideal, I feel, any developer worth their salt should consider...   Ignore screen size and develop your game assuming any resolution! This way, if someone is self-sadistic enough to try playing the game on a 2" 320x240 screen, so be it, but if they play it on a 100000000x100000000000000000 screen, all hail their C/GPU!   ... in general, make the limitation of resolution that of the CPU or graphics processor, not what you believe to be the standard. Like I said, "easier said than done", but that don't mean it's something that should be brushed away. Mip Maps exist for this reason, after all.
  3. Do you have a game idea/design you want to make? That could help you choose which engine to pick. However, both Unity 5 and UE4 are free, so, why not nab them both and experiment until you find one that's comfortable to you based on your work-flow and available tools.   As for the C++ question... In my opinion, if you want to be a serious game developer, then a very solid understanding of C++ is ideal. Sure, the engines may not require it off hand, but, if you're project is big enough, you may get to a point where you want to add new modules to the engine, and that's going to take some solid C++. If, on the other hand, you're looking to do a Flappy Birds or Mario clone, then you may not need the C++ skills so much. Long term, though, they are a big thing to have!
  4. It sounds like your creatures are not under the player's direct control. Almost sounds like a Dwarf Fortress or Dungeon Keeper type of control. If that's the case I had some ideas.   Have the choice of whether a create enters the water to achieve it's goal vary from creature to creature. Some creatures can be petrified of water (instantly cancelling any order given to it that would lead to water) while others give it no mind at all (will go right in!) This may add to a creatures over all personality, and maybe even the drama for the player ("please open that door! Come on! WHAT DO YOU MEAN YOU DON'T LIKE WATER?!")   You mention flying creatures aren't effected by water... but what if they're in an enclosed space (like DF or DK)? Couldn't the water reach the ceiling? If it does, wouldn't the flying creature need to be effected by it?   Why limit the underwater actions to just doors? If the creature can open a door, can't they pull a lever or press a switch as well?   Maybe the creatures can even "rescue" other panicking creatures. If you have the petrified creature, who is suddenly engulfed in water, maybe he panics and flails. On the shore, a "brave" creature (who is otherwise idle) may see his panicked comrade and decide to save him.   I don't know how feasible any of that is with your system, but just some thoughts that came to mind.
  5. It's been quite some time since I last posted on this site. In fact, so much time has past that I figured it's better to start a new journal than to continue the old one. I've been getting back into C++ after a number of years away. I used to be decently skilled at the language... but I was a bit surprised at the new features it obtained since I left (there are still things about C++11 that I'm just discovering, and I haven't even looked at C++14 or the upcoming(?) C++17). However, one of the lovely new features the language had obtained was smart pointers (truthfully, I don't even think boost was around when I last worked with C++). Looking at all the shiny new C++ toys... I decided to start a C++ game. Ok... actually... I started about 4 of them since I came back to the language, but my most recent project has come leagues ahead of the others (and all it does is display a splash screen, then a blank window... lol). I'm not going to talk about the game or the project, really. It's too infant at the moment to be worth mentioning. What I want to write about is the Asset/Resource handling system I implemented! Asset System No... I'm not about to go around claiming I invented anything. See... Asset management (keeping track of loading and using images, audio, meshes, etc) has always caused me to bog down in a project. I know what I want to do, but I always had trouble wrapping my brain around the issue (I'm slow ) and every time I thought I grasped the problem, I'd get to a point where it didn't seem to work, whether that be because the system didn't work for all assets I wanted to use, or I couldn't figure out how to handling the loading of those assets, or... the biggest of them all... how to make the "manager" accessible to everything that would want to use it without making the "manager" itself, global. The solution came with the following realizations (thank you to the GameDev forums)... One class CANNOT rules them all, in this problem. Really check the responsibility of the class. Singletons don't help this issue. 1. From one class to three classes... per resource 0_o No matter how long I pondered the issue... no matter the coding tricks I tried to employ... I couldn't design a single, universal, "Asset Manager" class. Sure... I can stick "template" to the head of my class definition, but how do I load that "ASSET"? An image loads different than an Audio file. A Mesh needs an Image as part of it's data. I couldn't define one loader that loads them all. Not only was loading the asset an issue, but not loading the asset was an issue! I didn't want to load an asset unless I needed it, so I only really wanted to store the description of the asset in the manager and have the manager load it when requested. With more complex assets (like the afore mentioned Mesh), it would need to load not just the mesh, but it's underlying data, such as texture and material information. The next logical thought was to do something like this...class Asset{public: virtual void load(); virtual void release(); virtual bool is_loaded();}; ... and then rig the actual asset class we want (like an SFML sf::Texture, for instance) with the Asset base class we just created. But... this ends up confusing the real asset class interface with the interface defined in Asset. What if I have an asset class that actually has a method void load() ? Even worse, however, is that any object that obtains an instance of my asset has access to the ::release() method! WHY? Why would I want any other object, other than my asset manager, to release() ANY of my assets?! I don't! My real solution...template class AssetDescriptor{public: friend class AssetCache; virtual std::string name() const=0; virtual bool loaded() const=0; virtual bool operator==(const AssetDescriptor &rhs) const=0; virtual bool operator!=(const AssetDescriptor &rhs) const=0; virtual operator bool() const=0;protected: virtual uint64 _referenceCount() const=0; virtual std::shared_ptr& _get()=0; virtual bool _load()=0; virtual void _release()=0;};template class AssetCache{public: virtual void add(const std::shared_ptr &descriptor)=0; virtual std::shared_ptr& get(const std::string &name)=0; virtual bool exists(const std::string &name) const=0; virtual uint64 referenceCount(const std::string &name) const=0; virtual void unloadUnreferenced()=0; virtual void removedUnloaded()=0;protected: uint64 _getDescriptorReferenceCount(const std::shared_ptr &desc) const{ return desc->_referenceCount(); } std::shared_ptr& _getDescriptorAsset(std::shared_ptr &desc){ return desc->_get(); } bool _loadFromDescriptor(std::shared_ptr &desc){ return desc->_load(); } void _releaseDescriptorAsset(std::shared_ptr &desc){ desc->_release(); }};template class AssetPool{public: virtual void setPoolCache(const std::shared_ptr &cache)=0; virtual void loadPool()=0; virtual void add(const std::string &name, bool autoLoad)=0; virtual void add(const std::shared_ptr &desc, bool autoLoad)=0; virtual std::shared_ptr& get(const std::string &name)=0; virtual bool exists(const std::string &name) const=0; virtual bool existsInPool(const std::string &name) const=0; virtual uint64 referenceCount(const std::string &name) const=0; virtual operator bool()=0;}; That's it! Three template interface classes! Class AssetDescriptor: To the outside world, all we want to know about this class is it's name() and if it's currently loaded() or not. The virtual class has no methods for HOW to define any of that information. That's for the concrete classes (class TextureDescription : public AssetDescriptor{};) to define. The comparison operators allow for quick compares to see if two descriptors are describing the same thing (how ever the concrete classes want to do that), and an operator bool() which will allow the outside world to quickly check if the descriptor is valid (as in, it has information which can be used to load a resource). It has some protected methods as well... such as the actual _load() and _release() methods. A method to obtain the current _referenceCount() and a method to obtain a shared_ptr to the actual asset. The descriptor is the only place that holds the "description" for loading/creating the asset. It does the loading/creating when needed. It also is the source of the asset's reference count (once loaded). Of course, the interface is such that the outside world can only describe the asset. It can't load or obtain the asset once loaded. Class AssetCache: Add the AssetDescriptors to the cache, and it'll keep track of them for you. Being a friend to the AssetDescriptor, it can call the loading and releasing as needed. The cache's publlic get() method will check if the asset is loaded, call the descriptor's _load method if it isn't, then return a smart_ptr to the asset if load was successful. Of course, how the cache manages any of that is up to the concrete class. An std::unordered_map is my prefered way, and tends to be for most resources. Notice, also, that the AssetCache class is the only class with actually defined methods (all protected). These are hooks to manage the limitation of C++ friends. A derived cache class does not inherit the friendship of it's parent, but it does inherit the protected methods defined by it's parent, so these defined, protected methods are the gateway to accessing the protected descriptor methods. This is great! I have interfaces for describing assets and caching them! Two issues remained. How to access the cache globally Asset unloading/releasing is still EXPOSED!! Class AssetPool: AssetPool helps me with issue number two above, but also gives me one other benefit I'll explain in a second. In general, AssetPool has much of the same interface as AssetCache sans the unload/remove methods, but it adds a "setPoolCache" method. The intent is that I can create as many AssetPool instances as desired and, post creation, assign them to the cache the pool is going to work from. I then use the pool to add assets and obtain them. The other benefit to the AssetPool (while not directly forced by the interface) is that I can store the loaded assets in the pool (as well as in the descriptor). Doing so ups the reference count on the asset because the asset is being held (internally) by the pool, but since the pool need to obtain the asset from the cache, I'm not reloading an already loaded resource. If it's not clear, think of the pool as a "local" instance of the cache. Object A and Object B can both have their own pools pointing to the same cache. Object A then pools "imageA", "imageB", and "imageD". Object B pools "imageB", "imageC", and "imageD". The cache, which both pools are associated, only loads up four assets with assets "imageB" and "imageD" having a reference count of 2 (one per pool) while "imageA" and "imageC" have a reference count of 1 (as each is only being requested by one pool). I know what you're saying... "Ok, but the AssetPool still needs to be given an AssetCache. How do you do that without passing the cache around?" Locator classes: This doesn't have an interface class because you can't really interface a static class and that's what the Locator class is. NO! I'm not trading in a singleton for a static class. Let me show you how I use the locator... Let's look at the following...class TextureCache : public AssetCache{...}; // My project used SFMLclass TexturePool : public AssetPool{...};// Here's my locatorclass TextureCacheLocator{public: static void mapPoolToCache(std::shared_ptr &pool); static void setAssetCache(const std::shared_ptr & cache);private: static std::shared_ptr m_assetCache;};std::shared_ptr TextureCacheLocator::m_assetCache = nullptr;void mapPoolToCache(std::shared_ptr &pool){ pool->setPoolCache(TextureCacheLocator::m_assetCache);}void setAssetCache(const std::shared_ptr & cache){ if (TextureCacheLocator::m_assetCache == nullptr){ TextureCacheLocator::m_assetCache = cache; } // Notice how the cache can only be set once? Yeah... it's my little cheat.} ... now, above, I define a concrete cache and pool class for my Textures (assume I did the same for the descriptor), but notice how the TextureLocator only expects pointers to the interface AssetCache and AssetPool? This means that I can define TextureCache and TexturePool any way I want, as long as it conforms to the interface (obviously), but I can also do the following...class TextureCacheEx : public TextureCach{...}; ... and the locator still works! Also, even though I extended TextureCache, I don't have to extend TexturePool in order to use the locator class as is. Conclusion: Even though I'm using a static Locator class, no objects (other than the one that creates the initial asset cache) have any way of touching the cache except through AssetPools. Any number of AssetPools can be created by any object that needs them, and these objects can use the locator to assign the cache to the pool. As far as the object is concerned, they have their own asset system via the pools, but in reality, they're all sharing through the cache, and the cache handles all of it's loading through the descriptors. Anyway... this is probably not new to anyone, but I hope someone finds it useful. At the very least, this is a (very large) reminder note to me about this system, in case my repository explodes and I loose the original code. If anyone did find it useful, feel free to use or borrow any of the above code and use it as a jumping off point. If anyone has any suggestions for me on how I'm using this, I'm all ears. It's working great for me so far, but I may be missing a shortfall. Also... I want to thank the forums on this site from which I pieced together the bits of information that lead me to this system. Ok... I'm done typing now... Seriously I mean it Right this moment. No more talking from m[END OF LINE]
  6. I'm not entirely sure what you mean when you say "Effective Sculpting in a Game Engine"?   There are games out there that allow for content creation in game. For instance the Cube2 engine is an FPS engine which has a built in cube-ish based multi-user level editor. Players can create levels together, even while switching between editing and the primary game. This is a sculpting system, in effect.   Or... of course... there's minecraft. The whole point of the game is, more or less, sculpting. It's also voxel based as well as an FPS style game.   A little more obscure is a game called Starmade. This is, effectively, Minecraft in space, but many of the individual blocks serve a purpose in the effectiveness of starships which the players build (and, the players build amazingly complex ships in both function and design).   Furthermore, there's "games"(?) like Secondlife (or OpenSim if you want the open source version). At it's core, it has a full terrain building system and object creation (using the manipulation of PRIMitives). While the game is rather dated, it's content creation ability is quite nice.   If you're looking for games ideas, these are games you could look into and get inspiration from... not sure if they'd be considered "effective" (though, their players generally feel they are).
  7. You've given me quite a bit to mull over. Thank you.
  8. In some ways what I have in mind will be similar, but I'm planning the crew in my game to be more numerous (possibly in the hundreds) and far more autonomous (like the dwarves in Dwarf Fortress). Also, the player will have control (via "Captains Orders") over what the ship is doing in combat (course, target locks, etc)     Well, here's the thing I wanted to avoid. Obviously walls and floors are relatively simple. They have a structural max, a current structural value, and perhaps some durability and resistance ratings. Other components, such as power conduits, water control systems, etc, would contain more complex data. If I placed a full instance of these entities in every tile that contains an entity, that could lead to a fairly large data file (and memory footprint) for even a lower to mid-range map size. This is why I'm thinking have an entity list containing one instance of each entity with all of their baseline values, and have the map tile store only an index and vector of value differences.   As for the map itself, I was thinking a 3D vector data structure.
  9. Hello there.   For a little bit now I've been coding a game. The basic idea is I want it to have a general Dwarf Fortress aesthetic, set on a starship. Basically, where Dwarf Fortress simulates dwarves within a fortress, I want to simulate a crew aboard a starship.   While I've spent most of my time thus far reaquinting myself with C++ (I've been away from it for almost a decade) and getting what I think are the core system elements written (uses SDL2, a nice Handle system based on std::shared/weak pointers, Game State Manager, etc etc)... but now I'm kinda past the preamble and want to get to the actual simulation.   Here's the deal... obviously, I'm planning a tile map for the ship interior. Structures such as walls, doors, floors, all included... but I want them to be destructable. I'm also planning that the ship will have full system layouts too... such as power conduits leading from a main reactor and distributing that power across the ship, and I want these overloadable and destructable. If power is lost, components attached further down the grid go dark. Furthermore, the power conduits will have a voltage limit and can "burn out" or even overload leading to explosions, etc. Other similar subsystems like water and waste management systems I'm thinking about as well.   What I'm trying to come up with is a decent structure to handle that kind of information without it being overwhelmingly large (for sizable ships) in memory or on the file system. My current idea is to create an entity list which will hold every possible structural item and all of the base values of those items. Then, each tile in the map would be an index into that entity list and a vector/map containing information regarding state change. For instance, if a Wall entity has a base structure value of 5, and is damaged for 2, then the map tile containing that wall will store "structure":3 in it's vector/map. If the wall looses all structure, then I would simply wipe the tile's vector and change the tile index to the "rubble" entity instead. The way I'm thinking, this should keep the size of the map (both in memory and on disc) rather small because only those values that deviate from the baseline would need to be stored. Does this sound reasonable, or am I missing something obvious in my logic?   In case someone may ask about how big I plan on making these maps... I want multiple z-levels (decks) and, while this may be way too ambitious, having a ship with the same interior space as... say... the Enterprise NCC-1701-D ... *cough* ... is sort of a hopeful goal.   Oh... yes... and I'd like to allow ship-to-ship combat on a tactical map as well. As one ship damages another, that will lead to the walls taking damage and power overloads, etc, etc. As that effects the crews of the ships, the performance of the ships in the tactical game go down (very directly). Therefore... yeah... eventually I'm hoping the game could support 2+ Enterprise-D sized simulations going at the same time.   Any thoughts or suggestions?
  10. [quote name='Gaiiden' timestamp='1302917158'] references references references!!! [/quote] Come again?
  11. [BLURB:] Sooooo... Perhaps I should work on smaller projects... hmmm. In any case, spent some time taking a look into python on Android, tried the pyweek challenge, and NAILED THE HELL out of SATs... not the school education kind. [DEVELOPMENT: Hell] Hmmm... Archetype needs to take a little break (not that I haven't already put it on the back burner). I've thought this many times, but still, I'll say it... I need to work on smaller projects. To that end, I tried my hand at the pyweek challenge that just occurred. For those that don't know, the challenge is to write a game, either alone or in a team, within one week, based off a theme that isn't revealed until the moment the challenge begins. This challenge was "Nine Times". So... did I succeed... Ummm, not exactly. Turns out, having to help move family from one apartment to another takes a hell of a lot of time (8 hours of day 1... lost). Nine hours a day due to my full time job doesn't help much either. Then, of course, my father's computer fails two days before the end of the challenge and who's the only one in the family that can fix it? Yeeeah... None-the-less I still spent most of my free hours working on something, and while I didn't have anything playable until 5 minutes AFTER the end of the challenge, I learned a lot! One thing I learned was that Android's SL4A is not a viable platform for writing games. I'm thrilled that there's a method for writing applications for the Android outside of Java and C++, but as I looked into the SL4A project, I soon realized that the Android graphics library was not exposed to the scripting languages. This is a HUGE oversite of the project, I think, and, as such, I lost a few hours of the pyweek challenge because I didn't realize this issue until I was preparing to develop my pyweek game on Android. DRAT! With any luck, SL4A will get a graphics hook and then we'll REALLY be cooking! HA! [TUTORIAL: SATs] Pyweek wasn't a total loss, though, as I learned and nailed Separate Axis Theorem collisions!! There's a bit of documentation out on SATs and it's all pretty good, but I figured I'd share my discoveries with my wide blog audience for no other reason than to solidify my understanding of the system. Firstly, I'd like to point out that this is for calculating collisions on 2D objects. While SAT works on 3D, I only really worked with 2D, and that's what I'm working with.Secondly... I haven't worked with sphere (or rounded) objects. It wasn't what I was focusing on when I was developing my application, and so, for the time being, I'm skipping rounded objects.Thirdly, SAT ONLY WORKS WITH CONVEX OBJECTS! These are objects that if you drew a strait line through them, the line could NEVER intersect the object in more than 2 locations regardless of where you drew the line.What is Projection: To begin let's talk about projection. What is projection? It's a shadow. For a 3D object projected onto a plane, the result is a 2D shape (or, if you think of the real world... a shadow). For a 2D object, the projection is a line with a length long enough to encompass the entire 2D object when viewed from the axis in which one is projecting. Huh? Well... let's think of a rectangle. The axises of a rectangle are the X and Y axis, and the projection of a rectangle upon the X axis would be the same as the length of the rectangle. Projection in regards to SATs: Let's stick with the rectangle for a little while and start talking about SATs... With the Separate Axis Theorem we can determine if two objects are colliding with one another if ALL of the axises of projection between the two objects in question overlap each other. If even a single projection doesn't, then there is no collision. Think of the two rectangles... I dare you to try drawing two rectangles in such a way that the shadows on the X axis AND the Y axis for BOTH rectangles touch but the rectangles AREN'T colliding. Go ahead. I'll sit here and wait for you... ... ... No? Couldn't do it? And that's the point. If all shadows for both objects are all overlapping each other, then your objects are colliding. If even a single pair of shadows ARE NOT colliding, then the objects ARE NOT colliding. That's the Separate Axis Theorem. Take your objects, find all axies in which you need to project upon. If even a single axis has a pair of projections that DO NOT overlap, then there is no collision and you're done. Finding Axises to Project Upon: Great! Now you may be wondering... "If I'm suppose to project upon some axises, what axises do I need to use?"... As it turns out, the axises you need to project against are simply the normal vectors for each side of your 2D object. Lets look at a little python code that does this... Code Example: 1.0 # This is a 10x10 rectangle centered at the origin. points = [[-5, 5], [-5, -5], [5, -5], [5, 5]] axises = [] # an empty list at the moment # We loop through the edges of the objects... # which just so happens to be the same as # the number of points. for p in range(0, len(points)): if p == len(points)-1: edge = [points[0] - points[0][0], points[1] - points[0][1]] else: edge = [points[0] - points[p+1][0], points[1] - points[p+1][1]] # Now that we have the edge, we need to find it's normal... There're actually TWO # normals you can use, depending on if you use the left handed or right handed # normal. For the most part, it doesn't matter which you use, as long as you're # consistent. # I'm going to use Left Handed normals.... norm = [edge[1], -edge[0]] # Or... (y, -x)... it's that simple. # At this point we've found our normal, which is more or less our axis. I say # "more or less" only because, for simplicity, our axis should be a UNIT vector. nlength = math.sqrt((norm[0]**2)+(norm[1]**2)) axis = [norm[0]/nlength, norm[1]/nlength] # proj_max: proj_max = dp projection = [proj_min, proj_max] Keep in mind, we would have to do with for ALL axises from BOTH objects ON BOTH objects. Huh? I'll explain next... Putting it All Together... Simply: So now you see how we get our axises to test upon and how to calculate out projections... let's put it together! Code Example: 3.0 # obj1 and obj2 are assumed to be a list of points like used in Example Code 1.0 def collides(obj1, obj2): # Assume the CalculateAxises function does the same as Example Code 1.0 # and returns the axises list. # Calculate the axises for the first object o1axises = CalculateAxises(obj1) for axis in o1axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # Assume the Overlaps function returns true if the two projections # overlap and false otherwise. if not Overlaps(o1proj, o2proj): # As soon as ONE pair of projections DON'T overlap # we KNOW there's no collision. Done. return False # NOPE! Not done yet. We now have to do the SAME THING for the axises of the # OTHER object. # Calculate the axises for the second object and repeat the same as we did above. o2axises = CalculateAxises(obj2) for axis in o2axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # Assume the Overlaps function returns true if the two projections overlap and false # otherwise. if not Overlaps(o1proj, o2proj): # As soon as ONE pair of projections DON'T overlap # we KNOW there's no collision. Done. return False # We've now looped over all axises for both objects. If we're still here, then # ALL PROJECTIONS OVERLAP! # We've COLLIDED! return True And now you know, using the Separate Axis Theorem, whether or not the two objects collide. Of course, you usually want to know a little more than that... like, if they've collided, how do you break OUT of the collision? Turns out, that's not too much harder than what we've already done. Putting it All Together... MTV Style: No... not the TV station. In this case, MTV stands for Minimum Transition Vector... or, more simply... What's the quickest way out of here!!! What we want is a vector showing us the way to non-collision safety. All we need for that is axis in which the minimum overlap was found. Lets go to code, shall we? Code Example: 4.0 def collides(obj1, obj2): # These will hold the information we need to find our MTV. # For now, they're None... meaning we didn't find anything yet. MTVOverlap = None MTVAxis = None # Calculate the axises for the first object o1axises = CalculateAxises(obj1) for axis in o1axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # We're getting rid of the Overlaps function from before, and using the # Overlap function (we dropped the 's'). Overlap will return a scalar # value equal to the amount of overlap between the two projections. # If there is no overlap, then Overlap will return a 0.0 ol = Overlap(o1proj, o2proj) if ol == 0.0: # We have no overlap... meaning we have no collision... meaning # we have NO MTV. We're done. return None # Here's where we do some new stuff... if MTVOverlap is None: MTVOverlap = ol MTVAxis = axis elif ol < MTVOverlap: MTVOverlap = ol MTVAxis = axis # Calculate the axises for the second object and repeat the same as we did above. o2axises = CalculateAxises(obj2) for axis in o2axises: # Assume the CalculateProjection function does the same as Example Code 2.0 # and returns the [min, max] projection. # Get the projection of obj1 over the axis. o1proj = CalculateProjection(axis, obj1) # Get the projection of obj2 over the axis o2proj = CalculateProjection(axis, obj2) # We're getting rid of the Overlaps function from before, and using the # Overlap function (we dropped the 's'). Overlap will return a scalar # value equal to the amount of overlap between the two projections. # If there is no overlap, then Overlap will return a 0.0 ol = Overlap(o1proj, o2proj) if ol == 0.0: # We have no overlap... meaning we have no collision... meaning # we have NO MTV. We're done. return None # Here's where we do some new stuff... if MTVOverlap is None: MTVOverlap = ol MTVAxis = axis elif ol < MTVOverlap: MTVOverlap = ol MTVAxis = axis # Ok... we've gotten this far, which means all projections overlap between # the two objects, so we want to return the MTV. We've already captured # the MTV, so we return it as a single vector... return [MTVAxis[0]*MTVOverlap, MTVAxis[1]*MTVOverlap] And we're done... Yeah.. ummm... for the most part... MTV Directionality: This little bit caught me for a while when I was figuring this out. I had done everything right, but, when I tested two objects as certain angles, instead of the MTV moving the objects out of collision, it'd send them further IN! It had occurred to me, after a couple hours of frustration, that... What is the MTV was pointing in the same direction as the colliding object. First thing I had to realize is that the winding of my object's points were important. Meaning, where they clock-wise or counter-clock-wise. For instance, for Code Example 1.0, the points in the "points" variable are counter-clock-wise. There's probably ways to determine this programatically, but, for simplicity, just say all objects must be drawn in the same winding. In my case, I was drawing in a CCW direction as well, so... I thought to myself... "self", I said, "during the collision, one object has to be moving and the other not" (simple situation). So, I decided that I would calculate the vector between the two objects... vector = collideeObj.position - colliderObj.position ...and normalize it... vector.normalize() Then I would get a normal vector of my MTV... MTVNorm = MTV.normalize(returnCopy=True) ... find the dot product between my direction vector and my MTV vector... dp = vector.dot(MTVNorm) ... and, for CCW winding... if dp < 0.0: # This inverts the vector. Same path, different direction MTV = -MTV ... and finally, reposition the collider by the MTV collider.position += MTV And there you have it! OBJECTS COLLIDING PROPERLY!! Caveats: Like I said, this works for N-sided objects. I didn't even look at rounded objects because I wasn't focusing on those (I was pressed for time). Also, the objects MUST be CONVEX objects, but that's more a caveat with SAT than my code. Lastly, there's no compensation here for fast moving objects nor complete inclusion (one object totally within another). If you want to do concave objects, simply create a group of convex objects and treat them as one object, except during collision testing. Conclusion: I hope at least someone finds this useful... but, at the very least, I can always look this back up if ever I need to code up SAT objects again. If anyone would like, I could post up a simple example program (in python), but for now, I need to eat dinner.
  12. [quote name='Terseus' timestamp='1299005162'] Oooohh man you save my day! I'm learning right now OpenGL with PyOpenGL following a tutorial for C (my main language, so I have no problem translating the code to Python) and I was having the same f***ing problem and you save me with the knowledge that I [u]need[/u] a valid OpenGL context created to be able to use glGenBuffers at all. A thousand thanks man, really. May the force be with you PD.: Sorry for my poor english. [/quote] Hey man! Sorry for the late reply, but I'm glad my insight was able to help you out! Truth be told, I'm still having a hell of a time with VBOs in general. Good luck in your project!!
  13. [BLURB:] Working on a 4X game, and the Archetype Engine is on hold thanks to the flipping camera! Also, my job goes from part time to full time and I've been exhausted! [DEVELOPMENT: Galaxy vs Archetype] It's a bit of a bad habit of mine. I'll work on a project for about a month or two, then I want to try something else. Actually, this only happens with my own personal projects, thankfully, and not those I do for work, but still, it's annoying. In terms of the Archetype engine, my VBOs have kicked my butt and now my camera... which I had thought was rather stable... turns out to be far from. Having spent a solid week trying to get it to work right, I'd decided to put Archetype on hold for a little while and switch over to a new project that, in time, should easily be mergible with the Archetype project. Ok, so I'm legitimizing the switch by thinking to myself that I'm just working on another aspect, but whatever... To anyone that reads this journal, you may have remembered one of my last posts saying how I was looking at playing some 4X games, but couldn't find one to satisfy me. To that end, I have started working on a project called "Ships"... weak title, I know... which will serve as part one of my 4X development. What Ships will be, is the "ship designer" portion of the 4X game. When the game starts, players will be presented with a ship designer and a starting sum of Production Points in which to assemble a fleet. The player will be allowed to design as many ships as they want, but their fleet would be limited to the number of production points available. Once the player as designed their ships and/or assembled their fleet, they then choose another player's fleet to compete against. At this point, the game will switch to the tactical portion of the 4X game, in which the two fleets do battle. At the moment, I've been poking at the game for about a week. I have written a custom config loader and a language string loader (for internationalization of the application). I'm currently working out in my head how I want to handle error handling and logging. I'm pretty sure I'm going to use Python's logging module, just not sure exactly how I want to integrate it. Oh... silly me... Ships is the name of the demo/game that is the first part of my 4X project... Galaxy is the name of the library I'm writing for the 4X game(s). Galaxy contains the currently developed config loader, language loader, and component manager currently developed. I'll be uploading the git repo of the game(s) to gitorious soon. [BUT WHY?!:] Like I said, I had a powerful hankering to play a 4X game, and there's so few for linux. Ok, to be fair, I wanted to play a 4X SPACE game, and there are so few of those. I looked into FreeOrion, but, sadly, the forums almost seem dead. The game runs fine, but seems empty of any actual life. More like a tech demo at the moment. Again, to be fair, this tends to be the case for a lot of unfunded open source games... and mine may even end up that way itself... but still. I tried playing some 4X games from Windows through wine, but, between incompatibilities with wine and a current dislike of microsoft at the moment, I couldn't play any of those. And so... I try to write my own. Still hard because I really want to PLAY the game. Eventually, I hope that'll be the case. [Personal Side:] Development on any of my projects has also taken a bit of a hit recently because as of mid February my part time job as database developer turned into a full time job as a database developer. I'm very happy about that, but the new hours are tiring me out by the end of the day. Once I'm home I usually just want to veg on the couch and watch TV or play XBox (yes, I know that's a little hypocritical after my previous statement about not liking Microsoft, but sue me, I'm human). Even on the weekends, once I've finished the errands I need to do, I'm ready to just relax and let my mind drift. I'm sure I'll adjust to the new schedule eventually and be able to get a little more personal project development in as time goes by, but still... things are a little slow at the moment. Holy moley! You're still reading this? Ha! Thank you. I hope to have more interesting news as time goes by. Catch everyone next time!
  14. [BLURB:] Ummm... Yup. I have textures and I export from Blenders [DEVELOPMENT: Archetype Engine] Ok, so I haven't been saying very much this month. I had a bout where I REEEALLY wanted to play a good space based 4x game, but failed to find one that fit my desire. After that, I tried X2: The Threat on Linux. Fun game, but a little too pricey at the moment for me to buy. This lead me to Freespace2 Open. FUN Game. Which just lead me back to wanting to continue my engine. Every false start I had in finding a game to play just kept me saying "well, I'll just make one, then"! I have a few new ideas kicking around in my head. My original idea is still a goal of mine, but I have new side realms to venture into with my engine as I develop it. Heck, nothing wrong with multiple projects. Anyway... A couple of days ago, I finished writing my first Blender exporter for 3D models. Nothing fancy yet. All it exports are the basics (verts, tex-coords, norms, and faces) and exports them into a OBJ-ish plain text format (I do seem to love adding ISH to all my stuff). Ironically, I haven't written a loader for my engine to load the model file yet because I'm still ironing out the details on how the graphic submodule (which I'm now calling "occular" instead of "view") is going to be organized. Along THAT line, I finally added textures. The demo I wrote it VERY simple. It creates a basic one color texture. I'll probably expand on that as time goes on, but image loading DOES work. And... that about wraps up this update.
  15. [BLURB:] Not dead yet! [PERSONAL:] Ok, I haven't worked on Archetype for almost a week because my favorite RPG table top group suddenly finds itself GMless and I decided to try giving the job a go. Not that I've actually started GMing. It's an online group that used a virtual table top (VTT) and I've been spending a week organizing, to the best of my abilities, stuff for my campaign. With any luck, it'll be worth the time put in. On top of that, I've suddenly developed a hankering for Space Opera 4X gaming again and, while MOO2 has been helping, I've really developed an urge to try my hand at writing a 4X game. Gah! I hate when my brain does this. But, if I don't sidetrack a little, I'll loose all concentration for any project (the "run and hide" way of dealing with things), so, I figure working on 2 code projects is worth trying. Besides, the code from the Archetype engine could be used for the 4X I'm thinking of... if not in whole, then in part. [DEVELOPMENT:] Which leads to a question I've been pondering. Thus far I've been working on Archetype's graphic system. Currently, there's nothing about the graphics system that makes it unusable by any style of game. As such, I've been wondering if I should split out my graphics from Archetype into another library, or just copy the graphic code from Archetype and past it into whatever 4X engine I decide to write. Of course, this question may mean that I have a flimsy idea, over all, on what exactly an "engine" is and what makes it different than a "library" or (in Python terms) a "module". In any case, I'm still hacking away at my code.