Jump to content

  • Log In with Google      Sign In   
  • Create Account


Zipster

Member Since 11 Mar 2000
Offline Last Active Yesterday, 12:51 PM
-----

#5089662 Best practice for presenting enumerated display modes?

Posted by Zipster on 27 August 2013 - 07:17 PM

We're currently working on the video settings UI for our project, and we've run into a bit of a presentation issue regarding the enumerated display modes. In our past DX9 projects, we presented a list of modes to the user in the following format:

 

<width> x <height>, (<refresh rate> Hz[, Widescreen])

 

However the issue in DX11 is that multiple display modes can be enumerated that have different refresh rate numerators and denominators, yet result in the same integral value when divided, regardless of rounding (i.e. 59940 / 1000 and 59950 / 1000). Plus, multiple display modes can have identical widths, heights, and refresh rate ratios, yet have different scaling values (unspecified, centered, stretched).

 

My question is, what's the best practice for building a list of unique resolutions for presenting to the user? We'd like to keep it simple so that the user is only making a choice based on width, height, and integral refresh rate (numerator / denominator), however if multiple display modes have the same values, which one takes precedence? Why would I choose 59940 over 59950?




#5087692 Determining effect order

Posted by Zipster on 20 August 2013 - 04:57 PM

It's difficult to give an exact answer without knowing exactly what effects can... well... affect in your game, but ideally, you don't want effect order to matter. There are ways to design such a system so that effects can be applied in an arbitrary order, and an intermediary layer can sort out the side-effects and make sure objects are actually affected in a sane manner.

 

The analog is a graphics engine which renders in two phases: the first phase collecting all the objects that need to render (or in your case, all the effects that need to be applied), and then breaking down the objects into their component pieces and rendering them in the correct order to minimize state changes, handle transparency properly, etc. (which in your case is breaking down a high-level effect into its low-level state changes and sorting them appropriately).




#5087360 about lines of code

Posted by Zipster on 19 August 2013 - 12:25 PM

I never use newlines, so technically I haven't even finished my first line of code yet :P




#5084456 Easy-to-use Version Control on Windows? Needs to be able to easily ignore cer...

Posted by Zipster on 09 August 2013 - 01:43 PM

 


I've looked at Perforce but it's not exactly affordable for me, and it uses a different system than what I'm used to (I want Checkout/Update/Commit).

 

Isn't Perforce free for less than 20 users nowadays?

 

 

It is, plus Perforce actually does use a checkout/update/submit workflow because it's a centralized VCS.




#5055797 Component Design in Component Based Game Engine

Posted by Zipster on 22 April 2013 - 12:13 PM

I'd be wary of having multiple systems modifying the same property of a Component. Instead, I would have one system that is responsible for setting the current population capacity based on various states (e.g. whether a building is in construction, how long has been since it was maintained, etc...).
 
Of course this doesn't necessarily mean you have a construction system, a run-down system (to track how long it's been since it was maintained), a population-setting system, etc.... They could all be different stages of the Update cycle of the same "building" system (assuming they all rely on the same set of components).

I wouldn't solve the issue of multiple systems modifying the same component value at the system design level, by only allowing one system access. One of the main reasons you completely isolate data and logic in this component design is to introduce a level of abstraction that allows the code structure to be independent from the data structure. However only letting one system modify a value couples the two structures together again and you lose the benefit of that abstraction.

 

Rather, I would solve the problem at the data level and use an approach that lets multiple systems modify a value in a well-defined way. You already touched upon such an approach with the various Modifier and Multiplier components. Generally speaking, you allow values to be backed by formulas, like x * A, (x + A) * B, etc., and allow systems to modify the inputs (A, B), whereas the constants (x) are sensible defaults or initial values. The formulas can have an arbitrary number of constants and inputs, and can vary per value depending on how you want systems to influence them. You don't necessarily have to implement such a system in the context of the component design, with individual components representing the various inputs and whatnot, since that seems as though it would get heavy with components for every input of every formula, and it's not really "game" code per se... however that's neither here nor there. The point is that systems aren't modifying raw values, but rather adjusting them in the context of modifiers/multipiers/bonues/etc., and you aren't gatekeeping them behind single systems. Best of both worlds.

 

Total amount would be the number of buildings of type x contained in this entity. I don't want a separate row for each type x building, but instead group them into a column (total_amount) instead.

An entity is a single building instance. What you're describing sounds like an entity to manage buildings, which could be the land entity (with a LandComponent) you mention later. However any given building instance wouldn't store the amount of its type. It would be redundant information on each building.




#5055037 Component Design in Component Based Game Engine

Posted by Zipster on 19 April 2013 - 04:00 PM

One entity for the player. This entity would have a PlayerBuildingComponent connected to the entity below.

I wouldn't model the one-to-many relationship by having the "one" reference the "many" in this case, but rather the other way around. The player entity wouldn't directly store which buildings it owns -- in order to retrieve that information it has to perform a query with a join, along the lines of what I posted earlier. This also enables a much looser coupling between players and buildings, since the player entity doesn't have to updated at all whenever buildings are created and destroyed.

 

One entity for the building in construction. This would be marked as a building by having a BuildingComponent (With variables for name + total amount). It would also have a ConstructionComponent with amount of time left until completed. The building is not yet fully utilizing it's potential, so it can only house 100 people while being constructed, it thus has a PopulationCapacityComponent with amount set to 100.

The name of the building should probably go in a separate NameComponent, because it isn't something that's particular to it being a building (just about everything has a name). I'm not sure what you mean by "total amount", but if it has to do with construction then it should go in the ConstructionComponent. If it's building capacity, then yes that makes sense to keep in the BuildingComponent. Whether or not you need a separate component altogether for capacity, depends on whether or not other types of objects can hold people. If it's just buildings, then you don't need a separate component. How you split up these components will be very specific to the gameplay and at what granularity you want functionality to be customizable and interchangeable.

 

Time passes on and the building becomes completed, but it should now house 200 people instead of 100. Is this the responsibility of the ConstructionSubSystem normally? I really don't want to move any logic to my components, so I'm keen on putting this kind of logic in the subsystem.

If the capacity changes as a result of construction being completed, then yes your construction system would increase the capacity. If the capacity goes down because the building is run-down and ill-maintained, let's say, then the "run-down" system would change the capacity. The BuildingComponent could then store the various various capacities, or multipiers (however you want that to work), so the different systems know how the building (namely its capacity) should change in these circumstances.




#5054658 Fastest data structure

Posted by Zipster on 18 April 2013 - 12:22 PM

Let's start with the most important question -- is it too slow right now? If it works, and it isn't a bottleneck, then it's better to continue with the rest of your project and only worry about the HashMap if it turns into a performance issue, or interferes with other parts of your implementation.




#5054322 Component Design in Component Based Game Engine

Posted by Zipster on 17 April 2013 - 03:48 PM

I've decided to quote all you responded with, given that I'm now zooming in on what I need to do. Basically it sounds like classical database design, but where entities have been separated into a specific ID table, and where you then just add any data to this entity with the component tables.

Ideally, yes, your entity "table" would only contain a single ID field, and each "row" in the component "tables" would reference an entity ID. An entity is then just the collection of all component "rows" with a particular entity ID. I put those terms in quotes because in all likelihood you wouldn't be using an actual database (i.e. MySQL, PostgreSQL, SQL Server, etc.), but rather something which implements a similar relational model.

 

So in essence any object which needs to have a uniqueness to it needs to be an identity?

Well, yes, the entity ID is unique, which by definition gives it identity... if I interpreted your statement correctly?

 

A follow up question to this is that of templates. Given that someone will be creating template "classes" to decide from: The player can chose a race for example, which needs to be predefined. One way of doing this would be to have xml files which you then use to insert into the component model, or perhaps even have a component which classifies certain entities as templates. Any experience using templates with component engines?

That's certainly one way of handling templates -- you create a template entity (commonly referred to as an 'archetype') from which you clone to create new entities.

 

There's also another approach based on the flyweight pattern where you can create two versions of each component "table", one which holds static shared data (max health, max speed, etc.) and one which holds dynamic individual data (current health, current speed, position, etc.). You then have two types of entities, your "type" entities which store shared data, and your "instance" entities would represent the actual objects in the game, and reference "type" entities for their shared data. It's analogous to the difference between a class' member data (per-instance), and it's static data (per-type). Essentially, you're just implementing static data in a relational model.

 

Lastly, there's a hybrid approach where you use archetypes, and each entity refers to the archetype from which is was cloned. Then, you allow each component field to be "nullable", where a "null" values indicates that the archetype value should be referenced instead of the entity in question's value. This should give you the best of both worlds in terms of memory and flexibility, since you can share data when it's identic to the archetype value and set it locally when it changes (akin to copy-on-write), at the cost of more complexity in the value set/get logic.




#5053572 Component Design in Component Based Game Engine

Posted by Zipster on 15 April 2013 - 02:46 PM

Am I trying to hard to create a classic domain model? Are there any "best practises" with regards to e.g. collections when using a component based engine? Is it more common to see denormalized data structures in component based engines?

I'm not sure if there's an established set of best practices, because even now there are a lot of different interpretations and implementations of the "component-based" model. In the interest of full disclosure, for a little over a year I was doing some very heavy database work as part of a project at work, and really grew to love relational data models and the separation of data and logic, so obviously this influenced what I believe to be one of the better implementations of a component-based design. In the case of collections, a collection isn't so much a literal object that contains other objects, as much as it is a result set of a particular query, namely one where you retrieve all objects with CollectionID = 'x' (or in our case, ArmyID = 'x'). The possible values of 'x', or rather the set of army ID's, can either be inferred from the distinct set of army ID's present across all UnitComponent's, or be stored on entities that contain an ArmyComponent. In the latter case you establish an informal constraint on army ID's, and the notion of "valid" versus "invalid" ID's, but whether or not you need that type of constraint is up to you. Usually you'd only have the ArmyComponent if an army needed additional information, and wasn't just a logical grouping or joining of units.

 

In this case, would building be an entity connected to a player via a PlayerBuildingComponent (or such)? I'm having difficulty actually separating entities and components at times, usually when relationships are involved (which I have quite many of).

Ideally, an entity is just a logical grouping of components, so there really isn't an entity "object" to add data to because it's a logical grouping, similar to the relationship between armies and units. It's all components. For player ownership, you'd have a PlayerOwnedComponent that can be put on any entity to indicate that it belongs to a particular player. For buildings, you would have a separate BuildingComponent that handles data just related to being a building. The rule of thumb is, if you have to ask whether or not a component needs to be separated into smaller components, it probably does smile.png It's a bit like the single responsibility principle, only when applied to data.

 

Concrete example of how it works in my game: Say a player has x farms. There is no interest for the player to see these farms as unique, so I would group them into some data structure which says: BuildingType: Farm, Amount: x. But then behaviour needs to be added to this entity (or component, depending on your answer to the above question), so we add ProducesFoodComponent to this entity. Am I on the right track with regards to making the Building an entity in this case, and then linking this entity building to my player entity via a PlayerBuilding Component on either the Player or Building entity? If I don't do separate the building data structure into an entity, I'll get components having children of components, which does not seem right.

This relates back to what I mentioned earlier about logical groupings and queries. You wouldn't have an actual data structure that groups farms, or even cares that they are farms. All the system cares about, is entities that have ProducesFoodComponents, and entites that belong to the player of interest (which will have a PlayerOwnedComponent of the correct player ID). Depending on your level of normalization, it will do a query not far off from this, to get the total food production amount for a player with ID 'x' (I apologize ahead of time for any syntax errors in my SQL!):

 

 select sum(food.food_amount) from produces_food_components as food inner join player_owned_components as player on food.entity_id = player.entity_id where player.owner_player_id = x

 

Now of course your implementation might not use an actual query language, but that's the essence of how systems would retrieve the information they need from the collection of components and relations.




#5053523 Component Design in Component Based Game Engine

Posted by Zipster on 15 April 2013 - 12:29 PM

There are quite a lot of collection components in my game. E.g. an Army contains many units. Is it suitable to have an ArmyComponent containing many UnitCpmponents? Is that a suitable level of abstraction for a component?

A unit may logically belong to an army, but that doesn't mean that a unit object needs to literally be contained by an army object. Components on components is just asking for trouble anyway. A better approach would be to either have an ArmyID property on your UnitComponent, that indicates which army it belongs to, or have a separate ArmyUnitComponent altogether which contains the ArmyID. In either case, units don't necessarily have to belong to an army if the ArmyID is invalid (or the ArmyUnitComponent isn't present in the latter case).

 

Another thing I've been considering is the level of abstraction for the buildings I'll have in the game and also connected properties. A player can create a farm, which produces food. A player can also create a barrack to construct units, but this building also increases the offense points of troops by 10%. These types of properties can obviously change (although not likely that any other building than a farm will produce food), and as such this should be customizable easily. My question is what level of abstraction the components should be? Should there be a BuildingComponent, ProductionComponent, and ResourceComponent? Or should there be a FarmComponent, ProductionComponent and FoodComponent? Am I making my components too granular?

This is just my opinion, but I would probably design the components around how they affect the gameplay as a whole, rather than the specific building or object to which they are tied. For instance, a farm may produce food, but what if you eventually want to have some other object that produces food? Instead of creating a FarmComponent and then trying to adapt or pigeonhole that into some other object later on, just create a ProducesFoodComponent (not a great name but you get the idea) that you can add or remove to just about anything in order to increase food production in your game system by +X%. Same thing with unit offense and production. You get the most flexibility by designing components so that they can be added to just about anything and behave as you expect they would, while understanding that might not always be possible.

 

One more thing, and this question is about sub systems. I intend on making the sub systems handle the logic, and only have the components store data. Does anyone have some tips & tricks regarding how to think about sub systems? I've read that one should aim for a 1:1 relationship between components/sub systems, I am not sure this would be the case for me given my current setup with regards to my granularity of my components.

It isn't a hard and fast rule that there be a 1:1 correlation between components and systems. That just tends to be close to what happens when you move your logic out of the components. However it's entirely reasonable for components to simply be tags, in which case they wouldn't have any logic of their own, or perhaps for multiple systems to interact with the same component (however in that case you'd want to question whether or not that component can be split apart).




#5050068 WritePrivateProfileStruct question

Posted by Zipster on 04 April 2013 - 01:51 PM

You can specify any data you'd like, including just a single integer. However the fourth parameter is supposed to be the size of the data, which you've specified as -1, that when cast to an unsigned integer is actually ~4.2 billion bytes, a bit more than the data you've specified ;) You should use sizeof(int) instead, which is the true size of the data (a single integer).

 

Alternatively, for just a single integer, you could use WritePrivateProfileString instead and encode the integer as a string. Or you could use the registry... there's a number of different options, so you're not locked into using a raw data interface for profile settings.




#5047301 Optimizing entity rendering?

Posted by Zipster on 27 March 2013 - 11:25 AM

A dirty flag seems entirely reasonable to store on your position component and set whenever the position changes. You can add setters to the component for changing the position that will automatically set the flag, and the render system can check that flag before it updates cached transformation matrices in your model component. Usually I'd be all for creating an entirely new RenderComponent just for this purpose, but I see the "position dirty" flag being useful in other gameplay scenarios and the model component is already handling a lot of render-specific stuff.

 

Another optimization you'll want to perform is splitting your rendering into three phases; an initial phase where you make a list of everything that needs to be rendered, a second phase where you sort all those objects by effect and material to reduce renderstate changes, and a third phase where you actually perform the render. You mentioned wanting to add a "renderqueue", but I wasn't sure if this is what you meant by that.




#5047024 Article Topics: Suggested Projects

Posted by Zipster on 26 March 2013 - 02:56 PM

I wrote an Asteroids clone maybe 13 years ago? Back when DX 7 was all the rage and DirectDraw was how you did your 2D graphics. I don't think I have the source code anymore and it would most certainly not be using DirectDraw, however I wouldn't mind taking a crack at a new and improved version for an article smile.png




#5045378 Database change management

Posted by Zipster on 21 March 2013 - 03:34 PM

In you're concerned about revision history, a clever approach I've seen used in the past is to have a 'changelog' table which stores rows of DDL that, when applied in order, can rebuild your database from scratch up to any particular point in time. So whenever someone makes a change to your database, whether it be schema or data, you turn those changes into a list of equivalent DDL statements and record them.




#5045350 Database change management

Posted by Zipster on 21 March 2013 - 01:41 PM

We've used SQL Server in the past for several of our online games, with merging and deployment between environments being handled by senior DBAs using SSMS and SQL Compare. A custom tool was built to handle data entry that used the ADO.NET framework for interacting with the database. For every environment (development, test, release, etc.), every user had their own private database, to which they could pull data from the master database, "check out" and "lock" data, edit it using the tool, and then check it back in (push it back to the master database). It was the same model Perforce used. The idea was that someone could edit data and muck up their own database without affecting anyone else, or sullying the master data, which as you mentioned was difficult to get back once it changed (we took backups of the master databases several times a day, but that's still a lot of work to lose if we ever had to restore).

 

We ran into a number of "pain points", such as how to handle users being out-of-date with new schema, making sure they were always editing current data, optimizing the push/pull between a user DB and the master DB so that it was as fast and efficient as possible, preventing user data from being destroyed at all costs during pushes, pulls, and schema updates, merging data between two users when their edits caused the same table to be modified, etc. Basically, the more the master DB and any given user DB "drifted" apart, both in terms of schema and data, the more problems we would run into. And this would happen quite often, depending on how long a particular user was working on a piece of data and not syncing from the master DB.

 

On top of that, the data entry tool itself had its fair shared of issues and bugs. The fact that a lot of our game data was architected in such a way that did not translate very cleanly to a relational layout, made its job a lot harder as well. Data was often presented to the user in such a way that made translation to and from the low-level DB objects (DataSets and DataTables mostly) quite error-prone, because it wasn't being presented relationally, but rather in the most intuitive fashion to the user.

 

In the end, we just keep slogging through and fixing bugs until everything was in a tenuous-but-mostly-working state, most of the time smile.png  I'm not really sure what else to add unless you have a particular question about anything.






PARTNERS