I am creating a snake game in C#/XNA for fun but it's a good opportunity to practice some good object design.
Snake Object
There's a snake object which is essentially a linked list, each node being a vector with X & Y co-ordinates which relate to the map.
Also a few properties such as whether the snake has just eaten (in which case, the last body node is not removed for this update), direction that the snake is moving in etc.
Map Object
The map (game area) holds its contents inside 2D array of integers - using an array of primitives to store the map should keep down memory consumption and be quicker (and easier) to iterate over than an array of vectors.
Contents are defined inside an enum {Empty, Wall, Snake, Food} which are then stored inside the array at the relevant co-ordinates.
A reference is also kept to the snake object within the map so that every call to render, loops through the nodes that make up the snake and render it into the correct position on the map.
Question!!
My question is... is this coupling too tight, in which case are there any suggestions (i.e. observer pattern) or is it okay for this situation...
I've tried to think of a way to decouple the snake from needing to know the co-ordinate system being used by the map, but can't think of a way to make it work and keep the positions each nodes relative to each-other.
Any answers appreciated, cheers!
"is this coupling too tight?" No, it isn't.
In this case, the code required to decouple it is bigger, more complicated, and harder to maintain than the code required to simply implement it with the coupling.
Furthermore, there is always going to be some level of coupling required. Coupling to "a coordinate system" is usually one of them in game development. You could, in fact, rigorously decouple your map and snake objects (again, not worth the effort), but they still need to share a common coordinate system in order to communicate.
I think you are already hinted the answer yourself. The current design of making the Snake referenced in the map is tight coupling between the two.
You might want to consider creating another Interface such as MapListener that the Snake will implement. The Snake will listen to the event that maps will publish and react to it, effectively making the Snake the subscriber for the event that the Map is publishing (such as rendering in the correct position as you say). You could even have ArrayList of Listeners so you have the flexibility of adding new Object in the map that would react to the event in the maps as your game becoming more complex.
For reference on creating the Listener, see this SO question How can I code a custom listener. While this example is listening for finishing download, you should be able to see the pattern in the accepted answer for creating custom listener for your game. Let me know if you need any clarification and I will adapt the code to fit your case.
Here is simple first thought structure:
create an interface called MapContainable
//marker interface
interface MapContainable {
}
interface MapMovable extends MapContainable {
///map movement specific contract methods here
}
class Snake implements MapMovable {
.....
}
This way, your map need not know if there are concrete objects called snake, food etc. You snake object need not know the existence of a Map. A snake just moves!
Related
I want to enable a gripper to do pick&place an object from a shelf. For this, I am trying to use trajectry optimization using KInematic Trajectory Optimization and I am using this deepnote. But the problem is when I add an object to the plant, also the object is considered in the optimization prog. How can I exclude this object from being considered in the optimization.
I am kinda new to the drake and I kinda don't know how to exclude an object from conraints.
Thanks in advance, I am kinda in rush :)
drake
Short answer: I think you want to create a separate MultibodyPlant to your KinematicTrajectoryOptimization that doesn't have the objects in it.
More generally, it's very common to have multiple plants flowing through your robot + control stack, e.g. one for the "robot model" and another for the "robot + objects in the world" model. (It's reasonable that the physics engine's model of the world would be different than the model in the head of the robot). Currently in Drake, it's more recommended to just load two independent plants, rather than try to add/remove objects from an existing plant.
This question bothers me for a long time. The basic vehicle counting program includes: 1. recognize a vehicle. 2. track the vehicle by features.
However, if the vehicle #1 was found at time t, then at t+1 the program start to track the vehicle, but #1 can also be found by recognizing process, then t+2 program two vehicles will be tracked, but actually just one #1 in the frame. How can the recognized vehicle avoiding duplicate detect?
Thanks in advance!
If I understood correctly, you are concerned about detecting the object that you are already tracking (lack of detector/tracker communication). In that case you can either:
Pre-check - during detection exclude the areas, where you already track objects or
Post-check - discard detected objects, that are near tracked ones (if "selective" detection is not possible for your approach for some reason)
There are several possible implementations.
Mask. Create a binary mask, where areas near tracked objects are "marked" (e.g. ones near tracked objects and zeros everywhere else). Given such a mask, before detection in particular location you can quickly check if something is being tracked there, and abort detection (Pre-check approach) or remove detected object, if you stick with the Post-check approach.
Brute-force. Calculate distances between particular location and each of the tracked ones (you can also check overlapping area and other characteristics). You can then discard detections, that are too close and/or similar to already tracked objects.
Lets consider which way is better (and when).
Mask needs O(N) operations to add all tracked objects to the mask and O(M) operations to check all locations of interest. That's O(N + M) = O(max(N, M)), where N is number of tracked objects and M is number of checked locations (detected objects, for example). Which number (N or M) will be bigger depends on your application. Additional memory is also needed to hold the binary mask (usually it is not very important, but again, it depends on the application).
Brute-force needs O(N * M) operations (each of M locations is checked against N candidates). It doesn't need additional memory, and allows doing more complex logic during checks. For example, if object suddenly changes size/color/whatever within one frame - we should probably not track it (since it may be a completely different object occluding original one) and do something else instead.
To sum up:
Mask is asymptotically better when you have a lot of objects. It is almost essential if you do something like a sliding window search during detection, and can exclude some areas (since in this case you will likely have a large M). You will likely use it with Pre-check.
Brute-force is OK when you have few objects and need to do checks that involve different properties. It makes most sense to use it with Post-check.
If you happen to need something inbetween - you'll have to be more creative and either encode object properties in mask somehow (to achieve constant look-up time) or use more complex data structures (to speed up "Brute-force" search).
First, I understand the difference between value and reference types -this isn't that question. I am rewriting some of my code in Swift, and decided to also refactor some of the classes. Therefore, I thought I would see if some of the classes make sense as structs.
Memory: I have some model classes that hold very large arrays, that are constantly growing in size (unknown final size), and could exist for hours. First, are there any guidelines about a suggested or absolute size for a struct, since it lives on the stack?
Refactoring Use: Since I'm refactoring what right now is a mess with too much dependency, I wonder how I could improve on that. The views and view controllers are mostly easily, it's my model, and what it does, that's always left me wishing for better examples to follow.
WorkerManager: Singleton that holds one or two Workers at a time. One will always be recording new data from a sensor, and the other would be reviewing stored data. The view controllers get the Worker reference from the WorkerManager, and ask the Worker for the data to be displayed.
Worker: Does everything on a queue, to prevent memory access issues (C array pointers are constantly changing as they grow). Listening: The listening Worker listens for new data, sends it to a Processor object (that it created) that cleans up the data and stores it in C arrays held by the Worker. Then, if there is valid data, the Worker tells the Analyzer (also owned by the worker) to analyze the data and stores it in other C arrays to be fed to views. Both the Processor and Analyzer need state to know what has happened in the past and what to process and analyze next. The pure raw data is stored in a separate Record NSManaged object. Reviewer Takes a Record and uses the pure raw data to recreate all of the analyzed data so that it can be reviewed. (analyzed data is massive, and I don't want to store it to disk)
Now, my second question is, could/should Processor and Analyzer be replaced with structs? Or maybe protocols for the Worker? They aren't really "objects" in the normal sense, just convenient groups of related methods and the necessary state. And since the code is nearly a thousand lines for each, and I don't want to put it all in one class, or even the same file.
I just don't have a good sense of how to remove all of my state, use pure functions for all of the complex mathematical operations that are performed on the arrays, and where to put them.
While the struct itself lives on the stack, the array data lives on the heap so that array can grow in size dynamically. So even if you have an array with million items in it and pass it somewhere, none of the items are copied until you change the new array due to the copy-on-write implementation. This is described in details in 2015 WWDC Session 414.
As for the second question, I think that 2015 WWDC Session 414 again has the answer. The basic check that Apple engineers recommend for value types are:
Use a value type when:
Comparing instance data with == makes sense
You want copies to have independent state
The data will be used in code across multiple threads
Use a reference type (e.g. use a class) when:
Comparing instance identity with === makes sense
You want to create shared, mutable state
So from what you've described, I think that reference types fit Processor and Analyzer much better. It doesn't seem that copies of Processor and Analyzer are valid objects if you've not created new Producers and Analyzers explicitly. Would you not want the changes to these objects to be shared?
I have a class that have multiple instance variables. I want to achieve two purposes with the class. It's possible that I may only use some variables for one purpose and sometime use both.
Here's a more concrete example. I want to create a class that every time the user tap the screen, a dog sprite and cat sprite appear with an animation. If tapped again, they continue to perform different animation. However, sometime I only want the dog sprite to appear and update. And some other rare times, I want the cat sprite to appear after a couple of taps after the dog sprite appeared.
The question is: does instance variable allocate too much memory? I'm highly concerned with performance, because I'm planning to make a memory-intensive game. Since it's hard to predict when I actually use all the instance variable, should I divide them into two classes? Let's divide the possible scenarios to get a better idea.
Only the Dog Sprite is used and the cat sprite never appears : The cat's instance variable is left untouched if left in one class.
The dog sprite appear first, then the cat sprite appear later : Both sprite will eventually appear. It's possible to divide it into two classes, but some methods are duplicated since methods such as the touch advance logic and animation are similar. But if we leave it in once class, scenario 1 could occur, which could possibly be solve without a lot of duplicate code being reproduced.
Other things could occur, but the problems is already discussed above. These are the pro and con from my point of view:
One Class Approach
Pro
Avoid some duplicate logic
No need to import multiple header that leads to some similar instance variable
Con
Possibly leave half of instance variables unused (including NSString, CCSprite, a lot of integers and floats, CCAnimation, CCLabelBMFont)
Two Class Approach
Pro
Less instance variables
Possibly inherit from the class without inheriting some unnecessary variables in the future
Con
Some logic are reproduced
It's difficult to decide which option I should use. Any suggestions would be great! Thank you in advance!
if (didHelp)
for (int x = 0; x < 100; x++)
NSLog(#"Thanks!");
I'm highly concerned with performance
You and thousands of other inexperienced developers. Seriously, there are two things you're most likely going to experience:
your idea is way out of proportion and no amount of performance optimization will make it work -> change your idea
performance won't matter the least bit and you simply wasted time
Performance is among the least important things a game developer needs to consider at the start of a project.
Why?
Case #2 is self evident.
Assessing case #1 with reasonable accuracy before you even get started requires experience. Even then it's difficult. Simply have a backup plan if feature X proves to be too technically challenging (or impossible). If you can't assess performance, and your idea won't work with any backup plan, again you have two options:
implement a different idea
create a quick prototype to find out the peak performance parameters: memory usage, CPU & GPU utilization, loading times, and whatever other fitness tests seem appropriate to find out if your idea is feasible within a few days, if not hours.
does instance variable allocate too much memory?
No, and allocated memory has very little to do with performance.
You can use class_getInstanceSize to see how much memory a class instance uses. Rarely ever will a class instance use more than 500 Bytes. However, this only counts memory allocated for instance variables - not the memory the instance variables may point to. In a cocos2d app it's fair to say that 95% of your memory usage will come from textures.
It's difficult to decide which option I should use
Always strive to:
write readable code
write maintainable code
write less code
write safer code
write code only once (avoid duplication)
EmbodiedD,
You are certainly worried about too much here. The heap is going to get quite large in most applications. One simple class will be irrelevant. When you have 1000 instances of a data intensive class then you might have to start thinking about profiling.
If you are worried about organization, that's another thing altogether.
If you are loading classA with var1 and var2 or loading classA with var1 and class2 with var2, its more a matter of how you were taught to do abstraction.
This is a somewhat open-ended question, and there are indefinitely many ways to approach this question. Therefore, this is my approach and may or may not fit in every scenarios.
There are cases when an instance variable could be replace -- however this should not affect your decision if necessarily needed. Instance variable should be used when needed. Do not perform endless calculation just to substitute a single instance variable. Do try to limit your instance variables into variables when it is not needed outside a certain scope. Thanks to the informative users that posted on here, instance variable left unused impact performance at such a microscopic scale that you should not worry.
From my point of view, a class should only have one focus -- on function and and should pass on any other information to other class that need it. Information should remain encapsulated -- with one function to maintain reusability in other projects.
One should focus on the relationship of the function. IT-IS is the relationship that say one object should inherit another. In reality, it's like a Sienna-IS a car. A boat-IS a vehicle. Therefore, these objects should inherit any information from it's superclass. On contrast, IT-HAS say that these class contain something, usually of a quality or component, that cannot be inherited. A sienna-IS a car, but a tire-IS-NOT a sienna. Rather, a sienna-HAS a tire.
Another important relationship is delegation. The fancy definition say it perform a task on behalf of another, much like how delegates in the US represent the people of their states. Basically, it pass a certain information saying to the other class, who should in good practice, not affect the other former class. The class should not know exactly who it pass on to, but know enough to pass on certain information. This process of not knowing the exact identity of the delegate is called coupling.
In my case, of cats and dogs, delegation along with IT-IS is subjectively the best answer. Your opinion may differ. A base class should contain all the information that the Cat and Dog share. And any other information that is needed, such as the sprite's position, should be passed on as a delegate to the other class. And based on what I wrote, a class should not, in normal circumstances, programmed to do two function; for a class do one function and pass on all other dutiful needs to another.
For example, in Fallout 3, a save game stores the state and location of every single object and NPC in the game, and only takes up a few MB's. How do they do that!?!?
And then, during game play, how is this data added/retrieved in/from memory such that it can be displayed to the player in real-time?
UPDATED: (I'm going to make you work for your answers :P)
Based on Kevin Crowell's answer...
So I guess you would have a rendering distance that would apply to objects and NPC's, and you would "SELECT" the objects and NPC's within the given range. However, what type of data store would you use in order to get these objects?
In other words, you would you have a gigantic array of every object in the game, and constantly update a smaller list that holds the visible objects to render?
Also, per Chaos' answer...
Would would happen if you eventually touched every object in the game? Would your save game get bigger and bigger? In the case of Fallout 3, I'm pretty sure there aren't "stages", where the past data could just be dropped. Everything is persisted when you leave/return to a location. So how do you think this specific case is implemented?
With all the big hardisks nowaday, even developers seem to forget how many bytes there are in a megabyte. So to answer the question in the title: games store large amounts of data by creating savegames that are several megabyte large.
To illustrate how big a megabyte is, it's 8 million bits. That is sufficient to encode 2^8000000 = 10^2666666 states. In comparison, there are only 10^80 atoms in the universe. Now in a (save)game there are multiple subsystems with distinct states; e.g. in a RPG each NPC has its own state. But how much of a state is there, really? Their position in a town might be saved as 16 bits (do you remember their exact position if they're walking around anyway?). Their mood/disposition/etc as another 8 bits, and that allows for more emotions then some people have.
When it comes to storing this kind of data in-game, the typical datastructure is a QuadTree. This is a datastructure that allows you to determine objects in a certain X-Y region in O(log N). In some cases, game developers find it easier to pre-partition the world in zones. This reduces the amount of run-time calculations. A good example was Doom. Its maps had visibility pre-calculated; for each point one could determine quickly to which zone it belonged, and for each zone the amount of visible objects was pre-calculated. This reduced the amount of objects that needed runtime visibility checks.
It can simply be mapping objects, or NPCs, to an X,Y,Z coordinate plane. That information that be stored cheaply.
During gameplay, all of those objects are still mapped to a coordinate system at all times. They just need to read in the save information and start from there.
I think you're overestimating the complexity of what's being stored/retrieved. You don't need to store the 3D models for the objects, or their textures, or any of the things that make up large parts of a game's size-on-disk.
First of all, as chaos mentioned, it's only necessary to store information about things that have been moved. Even then, you probably only need to store, for each of those, the new position and orientation (assuming there's not other variables involved, like "damaged"). So that's two vectors for each object, which will be around a grand total of 24 bytes per object. That means you can store the information for 40,000 objects per megabyte. That's an awful lot of objects to have moved around.
Restoring this data is no more complex than placing the objects in the first place. Every object has to have a default position/orientation defined for the game to put it somewhere, so all you're doing is replacing the default with the stored value in the save file. This is not complex, and doesn't require any significant additional processing.
In Fallout 3 in particular, the map is divided in a grid fashion. You can only see your current square and the ones immediately next. The type of data store is not really important - can be a SQLite database, can be a tree serialized to disk, or can be something else entirely.
...you would you have a
gigantic array of every object in the
game, and constantly update a smaller
list that holds the visible objects to
render?
Generally yes, but the "gigantic array" doesn't need to be in memory. And there are more lists - objects in current and adjacent grid square (you can be attacked from behind - not in visible list), the visible list, the timer list...
Would would happen if you eventually touched every object in the game? Would your save
game get bigger and bigger?
Could - if there is a default state table for everything, the save can contain only the differences. The save will then grow as you progress.
Everything is persisted when you leave/return to a location.
Nope. Items you drop outside of your house will eventually disappear. Bodies too, probably. Random monsters are respawned every once in a while. This is both convenient to game designers and consistent with the real world.
If you think about the information you need to save it's really not that much;
E.g.
Position
Orientation
Inventory
Health
Objective-state
There are lots more of course, many of which dependend on both the type of game and how the save structure is organized.
Some games like Resident Evil only allow saves when you enter a new zone meaning you don't have to store all the information for entities in both zones. When you "load" a save their attributes come from the disc.
As to how this is data is retrieved/modofied, I'm not quite sure I understand. It's just data in the consoles memory. When the player saves it's written to the save device, and when they load it's restored.
One major technique is differential saves: only saving state that's something other than its default. Compare and contrast "saving the state and location of every object in the game world" with "saving the state and location of every object in the game world that the player has moved or altered".
Echoing the other answers, the biggest savings comes from eliminating all unnecessary state data.
If you look at 8-bit side-scroller games, they will start discarding state as soon as things are offscreen, and oftentimes retain nothing, because their resources are too tight to keep around more than the minimum number of instances.
Doing it on the macro-level for a game like Fallout 3 is just a matter of increasing the scope of the problem. You start sectioning up the landscape by grid or other geometrical methods, and spawn/despawn stuff as the player moves from one section to the next. You ideally keep the size of each area small so that in-memory state is not high. You figure out the bare minimum of state needed to keep around NPC and item instances, and in the layout data you tag as much as possible to auto-respawn so that it doesn't need any state saved.
If you want to be pointed at a specific data structure, an example serialization format might be a linear stream indexed by a tree of pointers, where the organization of the tree corresponds to the map layout.
On a related note, game engines often employ Zip compression, to keep the size of all that content down and also make some operations faster.
Besides what everybody else said, i would like to add state doesn't necessarly imply just position and movement,but also properites for the respective state. Usually a Game Engine has a feature witch allows you to save the data of a certain class.
Say you have a Player class and you are well into the story, when you click save the possible data that can be stored is :
Where is the player located in the
level/map
What are his attributes :
health,mana,strenght,
intelligence,etc
What skills does he have.
What level is he.
Globally we can also have:
How many references (names that allow the engine to pick up an object from a list) to objects are being stored in that specific level,in other words when you load what objects should be loaded along with it.
Are we using physics, if so who uses it.
And many more. Fallout 3 has one type of save, another game will have another. It really depends on the genre and the engine in use.