• 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.

Smjert

Members
  • Content count

    30
  • Joined

  • Last visited

Community Reputation

152 Neutral

About Smjert

  • Rank
    Member
  1. Thanks Oberon and TheChubu, I kind of had the "solution" (at least for the issue I had) in my hands a couple of days ago already but I didn't realize it: I was already using a sparse array to dense array implementation to hold things, but I wasn't controlling where in the sparse array things were put.. and I didn't think to do that. Oberon: just want to say that it's not always feasible (or make any sense) to put components in the same system, I mean, like my example before.. why should I store a NetworkComponent, which is read and written by a NetworkSystem, inside a MovementSystem vs store it in the NetworkSystem? To solve that I have to store references to NetworkComponents in the MovementSystem. The only confusion I had was how to link the NetworkComponent with its PositionComponent (or vice versa). Now there's a caveat in having fixed mapping entity id -> index in sparse array... it's that the sparse array has to be as big as the highest entity id value. And moreover if you store components (and references to them) into systems, therefore duplicating them multiple times.. even if the entityid is just 24 bits lets, say, you still risk to use a lot of memory (depending obviously on how many systems there are, how many component types and how many of them are used by more than one system). So I guess that keeping them in the system works only if you don't have many entities, but when you start having tens of thousands maybe it's better to have them in a central place (or have them there from the start). Also if you do that sparse array->dense array for every component type, if you have a lot of entities using one type but not the others, you still have to allocate an array as big as the highest entity id value... and those sparse array will be pretty empty. But i guess that in this case, if they are that empty, it means that not many of them has to be looped onto, so one can use a dense sorted array instead of a sparse array, and do a binary search... or use some other data structure. Am i making any sense?
  2. Thanks for reminding me to check it again, more in depth.   Well yes, zealotry is never good and i've almost always think about OOP code not in term of deep inheritance hierarchies, or basically all the "bad" characteristics people give to it. At the same time i recognize that sometimes in the pursue of giving better interfaces, this complicates refactoring for concurrency and giving priority to data flow.   Here i was thinking of a loop that needs to access to components of the same type, one after the other. It obviously all depend on the pattern access and data sizes.   And this surprise me, i supposed that the fact that ECS talks about systems which have the logic and components are only data was to kind of enforce DOD.   As before i was still thinking of the same type of loop.   Well i find that to be pretty wrong too, as i've said with Kylotan. What i meant with normal (probably poor choice of word) is what commonly (and probably wrongly) people referred to inheritance based games which have to be despised.   Not trying to follow any specific religion, if it seems so is because i still want to evaluate them fully to understand what seems the best and the worst parts, keeping the worst ones limited to few areas, where possible. And you all are helping with that :).
  3. I see, while i wouldn't put logic in components (unless they are created by some scripting language, hello data drive design!), it really seems to me too that one cannot avoid to have that kind of association of entities and components you describe. I mean again i've seen articles solving that, as i've said earlier, storing components in a way that's easier and direct to deduce the association, but it seems that they sacrifice a lot of flexibility and runtime properties of an ECS system.
  4. Thanks i will check it! A couple of comments/questions though, if i understood it right, in the array you have components of different types one after the other, grouped by entityid? Wouldn't that be an issue for the cache, since the Systems, dealing only with some types, would end up loading components that shouldn't be processed?   I meant a different thing: components are all stored in systems, but when, lets say, updating the MovementSystem, NetworkComponents are not stored there, but in the NetworkSystem, so they have to somehow be passed to the NetworkSystem, in an way/order that matches the PositionComponent counterpart.   But, if i understood it right, this go "against" the Systems part if an ECS. The reason of having components separated by type in different containers and stored in systems, plus the logic be separated from data, is to avoid spaghetti code. Then also it's a matter of performance: components would need to access different parts of memory (stored in various components), which are scattered around... while having systems storing the components, they can process them in bulk. And it's also then easier to make the component processing concurrent.   I'm not sure what you mean here, but i might not have explained myself. With X and Y, i wasn't referring to PositionComponent coordinates, or even some generic field of a struct.. i meant indexes of the components inside their array, stored into their system.   That would guarantee that components of different types are contiguous, but the update pattern of an ECS is to update components of the same type all together, so with your layout you would have to jump around in memory. The ECS idea is to loop components not entities.   And in fact my question is also half a critique to try to uncover the pitfalls, or the easy optimizations, where thinking about how to structure the code and data isn't a premature optimization.   I'm not sure i follow you here; I wasn't particularly worried about how to associate entities and components on a debug or editor point of view, but how to solve the needs of algorithms/logic in the systems to work on multiple component types, in a way that cannot be independent from their association with the entity.   So you mean that for each component type there's a hash-table entityid->component index? Wouldn't this again blow up the cache, given that keys and values in a hash-table are not that contiguous? Or you actually meant something like std::unordered_map<int, std::vector<Component>> where the int key is the entity id and Component is the base class of all Components?   So you mean DOD and ECS are kind of working against each other? What, i think, i have understood is that while ECS per se doesn't dictate that one should use DOD (i've forgot a capitalized O earlier :P), it makes it simpler to use it, because separating code and data and then putting data all together in systems kind of follows what DOD "asks". Moreveover again, putting data in systems, so that it's contiguous etc, helps the cache. What i'm trying to understand now is how much of DOD can be used in an ECS without hanging up myself with premature optimizations and architecture rigidity. Sure the architecture won't be rigid as a normal inheritance based game, but deciding how to resolve the lookups means changing data structures and also the actual code that deals with the lookups. Probably it cannot be avoided, but again i'm trying to understand if there's some "gotchas" i'm missing here or it really ends up being a case by case decision.
  5. After reading countless articles around the net (from RandyGaul, T-Machine, articles or topics here in gamedev.net etc) i find them almost always lacking the description on how to efficiently resolve the issue of associating entity with components and vice versa (especially). Before getting into details i want to clarify that i'm doing all of these researches for a knowledge reason, not exactly because of a specific pratical need. I'm not doing any AAA, nor AA, but not even single A ( :P) games (just a for fun and study one).  What i'm trying to implement and research is the most data oriented way of dealing with components/entities/systems Now most articles suggests that systems should own the data/components and store them contiguosly when possible. Though 9 out of 10 the system described somehow need only one component type and or need to loop on each component to do work. I find this to be a bit unrealistic, and most often then not system need multiple component types and only half of the requested component types are actually stored in the current system. Moreover not every component owned by the system have a/the same counterpart (i.e. in a multiplayer game, client side, one can have entities with PositionComponent and VelocityComponent, so something not simulated by the server, and then other entities with PositionComponent and NetworkComponent, where the second stores the remote position of the entity; both of these combinations would need to be processed by a MovementSystem lets say). And again it's not said that it is wise to try to process all the existing PositionComponents if only few of their NetworkComponent got updated... but this would either require a dreaded if/branch or an (expensive?) sort of the NetworkComponents, so that all the modified ones are near together. So in a situation like this especially where you have a NetworkComponent that is owned and modified by a NetworkSystem, how do one then associate the PositionComponent stored inside the MovementSystem (lets say) in some position X with the NetworkComponent stored in the NetworkSystem in some position Y, with X and Y not known in advance? I would think that the entity id should play some role here (or THE role), but again, i fail to see on how to do it efficiently. I know i can actually have an Entity class rather then only and ID, have handles to the components the entity is made of, though then i would have to store the entity id on each component too... and then do several lookups to first retrieve the entity and then the NetworkComponent (if i'm in the MovementSystem, processing PositionComponents), but doesn't this kills the cache? Another way i saw is to have a 1 to 1 mapping between indices of the components among all the systems, so that the index = entityid. But this yields to poor memory usage/holes due to entities obviously not being made always of all the possible component types. Yet another way i've seen is to make some assumptions on what group of components might be needed together and so store them together, but this seems very inflexible to me, especially when thinking of creating entities with "custom" groups of components at runtime. Other ways are simply.. avoiding the situation designing either systems that require only one component and somehow receive data to apply to those components as input, already magically sorted in the right order so that each one is applied to right component. Or yet again having systems that work on components which always have a/the same counterpart. I understand that in several cases the required indirections to get another component aren't that bad because the lookup doesn't happen every frame.. though i'm concerned when this happens and it doesn't make sense to rearrange systems in another way.   TLRD: I'm trying to learn and research the proposed most efficient ECS, which follows DoD. It's all fine and dandy but i see holes in usability/flexibility (and performance) anyway when not having the ideal situation where you have systems dealing with one component, but actually multiple components not owned by the system.
  6. Ok unfortunately the method i use is not the correct one. I mean the idea of slowing down the current velocity and then give thrust with the main engines in the heading direction doesn't make the velocity turn beyond a certain point and it will never make the velocity vector near enough to the heading. What i should'have though earlier is: what is the "best" force that drags the velocity vector "near" the heading (especially since in the end i want a circular motion)? The centripetal force! I simulate one using the right local vector (because i'm currently dealing only with right turns ). Now the problem though is to calculate the component of that force vector that acts as a deceleration for the current velocity. What i thought is to obtain the magnitude of that deceleration vector doing dot(-velocityDir, forceVector.normalized) and then multiplying it to the magnitude of forceVector. Then as earlier i do dot(velocityDir, headingDir) and then use it to divide the previous calculated magnitude and then use the result for the force with heading direction. It kinda works, but the speed grows a bit too fast (like 10mm/s) so i think there's something wrong. I've checked that the dot product between the resultant force and the heading direction is always around 0. Also probably this doesn't support the case where the angle between the velocityDir and the centripetal force applied is > 180, where i have probably to flip some signs or the like..
  7. I was thinking out loud hehe, but thank you for your help. Now i'm left with calculating the correct amount of deceleration needed for a particular turn, but that should be easy with circular motion equations.
  8. Yes transform.forward is normalized. I retried to write it with the dot product Vector3.Dot(currentVelocityDir, transform.forward); and using that value to divide the X Netwons and.. it worked! Or at least this is what it looks like even if, and i think this is due to rounding errors etc, i have a 0.001 increase of speed every second. The dot between the velocity and the total force is not always 0 (for instance 7.723626E-08), but still a very small value and that's why there's that increase in speed i suppose. And to keep velocity really constant i have to set it manually if > then expected one.  
  9. So let me write this in Unity (C#) code and see if i understood it right (just testing there): Vector3 currentVelocityDir = gameObject.rigidbody.velocity.normalized; Vector3 currentHeadingDir = transform.forward; // This is kept up to date by Unity float objMass = 10; gameObject.rigidbody.AddForce(objMass * (-currentVelocityDir)); // Force to decelerate at 1 m/s^2 float cosAngle = Mathf.Cos(Vector3.Angle(currentVelocityDir, currentHeadingDir)); gameObject.rigidbody.AddForce((objMass / cosAngle) * transform.forward); So this should be right? Because i'm not getting the correct result (the obj accelerates then suddenly lose a lot of speed, then accelerates again etc).   EDIT: Maybe i should add a bit more information, basicly i'm trying to simulate some assit engines that helps the spaceship to bank like an airplane but in space, but this engines have limited power. So the idea is that until the velocity direction doesn't correspond to the heading (or basicly the difference is less than some error value) i simulate an engine that decelerate on the opposite direction of the velocity and the main engines accelerating back to have constant speed, in the spaceship heading direction. Evochron uses this idea for instance (but i'm not sure about the method).
  10. Here is the problem:   I have a spaceship flying into space (3D world), so no gravity, no frictions etc, with a certain velocity and direction (heading). The spaceship changes heading, the velocity direction clearly remain the same, then i apply a force of X Netwon in the opposite direction of the velocity. Now i want to apply a force in the heading direction so that it counterbalance the deceleration due to the previous force.. meaning that the velocity length vector has to be constant (but clearly the direction won't be). It "should" be simple but for the life of me i can't get the amount of Netwon i have to give.
  11. I'm using Ogre3D 1.7.1. What i'm trying to do is to create a camera that rotates around and arbitrary point (like in a space game, or better example like Homeworld). This arbitrary point is the max distance i can zoom in (+20 units in forward direction from the current camera position/rotation). This is how i calculate things: Current camera rotation expressed with quaternions Quaternion GameCamera::GetCameraRot() { Quaternion yaw = m_pCameraYawNode->getOrientation(); Quaternion pitch = m_pCameraPitchNode->getOrientation(); Quaternion roll = m_pCameraRollNode->getOrientation(); Quaternion rot = yaw * pitch * roll; return rot; } Vector3 GameCamera::GetMaxTranslation() { Vector3 maxTrans = Vector3(0, 0, -20); Vector3 result = GameMath::VectorRotate(maxTrans, GetCameraRot()); return result; } I rotate vector (0,0,-20) because the starting forward vector is (0,0,-1) (the camera forward direction). VectorRotate is a function that rotates a vector by a quaternion, i take it from gamedev math book, so it should be correct. The calculation of the rotation origin Vector3 GameCamera::GetRotationOrigin() { Vector3 rotOrg = GetPosition() + GetMaxTranslation(); return rotOrg; } I will not show (if it isn't needed) the code where i use this functions to rotate the camera but the problem is that after i rotate it a bit the MaxTrans vector y component changes sign and strange things happens: Quote: 16:17:39: MaxTrans: x = 0 y = -14.0679 z = -14.216 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -14.1174 z = -14.1668 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -14.1914 z = -14.0927 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -14.2895 z = -13.9933 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -14.5315 z = -13.7417 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -14.956 z = -13.2785 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -15.7603 z = -12.3131 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -17.1793 z = -10.2406 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = -19.1864 z = -5.64636 16:17:39: RotationOrigin: x = 0 y = 50 z = -20.0001 16:17:39: MaxTrans: x = 0 y = 19.5332 z = -4.29566 16:17:39: RotationOrigin: x = 0 y = 89.0664 z = -28.5914 16:17:39: MaxTrans: x = 0 y = 14.1914 z = -14.0927 16:17:39: RotationOrigin: x = 0 y = 89.0664 z = -28.5914 16:17:39: MaxTrans: x = 0 y = 14.1914 z = -14.0927 16:17:39: RotationOrigin: x = 0 y = 89.0664 z = -28.5914 16:17:39: MaxTrans: x = 0 y = 14.1914 z = -14.0927 16:17:39: RotationOrigin: x = 0 y = 89.0664 z = -28.5914 Why? [Edited by - Smjert on October 31, 2010 5:13:05 PM]
  12. I have a shader that simply output the Z (+ a bias) for each pixel to draw a shadowmap. On my laptop where i have an Nvidia card it works well, but on ATI the depth test fail and my shadow/lights aren't shown (PIX says that the depth test fail after the vertex shader, the fragment isn't executed). I already tried to disable depth check and write from the material.. but nothing changed.. what could it be? I googled around but i didn't found anything about differences between Nvidia/ATI about this and how to solve. Nvidia card is: Geforce 8600 GO 256MB Ati card is: Sapphire Radeon x1950 Pro Ultimate 256MB
  13. I have a shader that proceed 2 lights every one pass. It works well with 2 lights (compared to the 1 light in one pass version, even if it output 2fps less :P), but when i add a third light (or generally when there is an odd light number) in my world the shader perform bad, because it proceeds one light that doesn't exist. How to avoid this? Since with branching the code is still executed.. The only way i can think is to mix the two shader (2 lights in one pass, 1 light in one pass) based on how many lights there are in the world, and i have to do this in the C++ part right? There's no other way?
  14. I have the latest PIX (from March 2009 SDK). I compile my project in debug mode with D3DXSHADER_DEBUG and D3DXSHADER_SKIPOPTIMIZATION. I cannot understand how it works the debug of a pixel shader when there's branching in the code. I have this snippet of code: [...] // If it's out the inner cone we have to low the intensity if (cosInnerCone > cosDirection) //line 75 { // if it's out the outer cone, it must be black if(cosOuterCone > cosDirection) //line 78 { lr.diffuse = float4(0.0, 0.0, 0.0, 0.0); lr.specular = float4(0.0, 0.0, 0.0, 0.0); return lr; } float cosMax = cosInnerCone - cosOuterCone; //line 85 float factor = (cosDirection - cosOuterCone) / cosMax; lr.attenuation = lr.attenuation * factor; } float3 HalfAngle = normalize(LightVector + EyeDir); //line 90 [...] and this is the respective disassembly: #line 75 if_lt r2.w, c1.x #line 78 add r3.w, r2.w, -c1.y cmp r4.x, r3.w, c18.x, c18.y if_lt r2.w, c1.y mov r5, c18.y // ::ComputeLight<8,9,10,11> else mov r5, c18.x endif #line 85 add r2.w, -c1.y, c1.x // ::cosMax<0> rcp r2.w, r2.w mul r2.w, r3.w, r2.w // ::factor<0> cmp r6, r3.w, r2.w, c18.y // ::lr<8,8,8,8> #line 75 else mov r5, c18.x mov r6, c18.y // ::lr<8,9,10,11> mov r4.x, c18.x endif #line 90 mad r1.xyz, r1, r1.w, r2 When i start to debug the disassembly and i step into line 75 (the if_lt) the blinking cursor divides from the yellow arrow.. i mean if i continue to step the cursor go down line by line executing it.. but the yellow line go where the program should be. I mean if if_lt is false, i expect that the cursor and yellow arrow goes together to line 75 (else), but isn't like that.. and it seems that all line are executed. Also i can't understand why lines like 90 and after are executed since there's a return..