51

Go with the second approach, simply due to the fact that you can introduce new resource types or items at any time without having to rewrite or update code (data driven development). Edit: To elaborate a bit more on why this is in general good practice, even if you're 100% sure some value won't ever change. Let's take the console game example mentioned in ...


39

First of all, it's way less clutter. If you have a position, a velocity and an acceleration, that's already 6 variables you have to deal with, 9 in 3d. Secondly, and this is the most important part, it grants you access to many ways to use or change them. For instance, getting the length of the vector, normalizing it, adding them together, dot product, ...


31

One quick way to get key-value pairs in Unity's inspector is to define a serializable entry class, and then use an array or List<> of them. eg... public class SpellAnimationMap : ScriptableObject { [System.Serializable] public class SpellAnimationEntry { public Spell spell; public AnimationClip animation; } public ...


29

A rule of thumb is that you use different classes when objects require different code and instances of the same class when the objects only require different values. When the resources have different game mechanics which are unique to them, it might make sense to represent them with classes. For example, when you have Plutonium which has a half-life time ...


27

At first you see that your commands are in the form of a list, so your first instinct might be to recreate that structure, and each dwarf will run through that list in sequence. What I suggest though is to break the list into steps, with each step having prerequisite(s), and then you run the entire command in reverse. Let me demonstrate with an example: ...


15

Compare the function signatures of both RotatePoints versions. Lone variables: void RotatePoints( float *out_x, int x_interleave_out, const float *in_x, int x_interleave_in, float *out_y, int y_interleave_out, const float *in_y, int y_interleave_in, float angle, int count ) { float s = sinf(angle); float c = cosf(...


14

I would like to add there are two extra options: Interface: you can consider it if the resource class would be just a "storage" for 5 integers and each other entity would have different logic regarding resources (e.g. player spend/loot, city produces resource). In that case you might not want a class at all - you merely wanted to expose that some entity has ...


11

Quadtrees typically store and retrieve rectangles. A point is a specific case where width and height are zero. The following logic is used to find home for new rectangles in the tree, starting with the root node: void Store(Rectangle rect) { if(I have children nodes) { bool storedInChild = false; foreach(Node childNode in nodes) ...


11

2D hexagonal maps are a representation of spheres packed in a flat (2D) tray, with each hex centred on the equivalent sphere, and allow distances between cells to be determined to workable (for gaming purposes anyway) accuracy, just by counting the number of hex cells through which you step. The equivalent 3D representation is the face-centred cubic (FCC)/...


11

If you can make sequences pretty general, there's not much of a spaghetti code. In case of deliveries e.g.: WorkTask operates with a WorkPlan. Workplan says what kind of resource unit must pick, from what kind of house, using which walk animation, using which work animation, time to work and all such details. So in the end WorkTask might look like: Find %...


11

Readability > Writeability I feel like it's just slow me down and barely has any benefit other than organizing your code. You are correct in that it (slightly) slows you down writing that code. However, you write it once in the beginning and from then on everytime you come back you are going to read it. So optimizing the reading speed will do much more ...


9

Tiles and icons (even in UIs like window systems) are often in a size like 16x16 or 24x24 to make it easier to modify the tiles. Most times the tile size is a multiple of 8 because of the folowing reasons. It is relatively easy to shrink a tile with the size 32x32 to 16x16 by simply putting 4 pixels together (e.g. create the median/average of the 4 pixels). ...


9

Is there some advantage to having each attribute laid out contiguously in memory? It's better for cache locality of data access. Memory access is slowest part of all modern computing systems. As memory buses pull in multiple bytes in "cachelines" and most modern CPUs will prefetch memory that it detects are being accessed contiguously, keeping data that is ...


8

You're overthinking it. Let's be real for a second here. What you're doing is creating a log flow that is essentially: var result = randome.next(0, hittable.maxvalue) foreach outcome in hittable if result < outcome.max_value return outcome // Reached the end of the table without finding an outcome // Probably an error here, but let's fake ...


8

Operator overloading. Vector v3 = v2 + v1; There is now only one place in your code where you have to write, test and debug vector addition, as opposed to tens, hundreds or thousands. Obviously vector addition is an overly simplistic example, but there are more complex vector operations and the same applies to those too.


7

If the tables are stable (don't change), you can get an O(1) sampling via the Alias Method. It almost certainly isn't worth the trouble if the tables are smaller, though. https://stackoverflow.com/a/6641764/720860 http://en.wikipedia.org/wiki/Alias_method http://pandasthumb.org/archives/2012/08/lab-notes-the-a.html http://www.keithschwarz.com/darts-dice-...


7

As mentioned in PeterT's comment, you don't need to load all of your levels at once; instead you just load the current level and when the player transitions from that to a new one, you unload the current and load the new. That gets you down to about 100mb (the raw per-level cost), but we can go lower still. Consider a cube; right now you're defining each ...


7

Depending on your needs there are different data structure that you can use for geometry representation, before I answer your question I need to point out that geometric representation are usually chosen based on two basic factors, Topological Requirements: this includes the types of meshes you are going to store, triangles only? n-polys ? regular, ...


7

Create an intermediary table that maps Pokemon to learnable skills: Now you can select all the learnables for a Pokemon by name: SELECT LearnableSkills.ID FROM LearnableSkills, PokemonLearnables, Pokemon WHERE LearnableSkills.ID = PokemonLearnables.LearnableID AND PokemonLearnables.PokemonID = Pokemon.ID AND Pokemon.Name = 'byte56' Or by ID: SELECT ...


6

Database reads are usually via network and from hard-drive. That means database queries will always take a few ms, no matter how simple they are. Databases can get faster with in-memory techniques and smart database designs with good indexing concepts, but their speed is often still insufficient for real-time processing. Blocking your process while a ...


6

Do the simplest thing that works, especially early on. If you've ever seen videos of triple-A titles in alpha, you'll know how slow / buggy they are. This is normal; in fact, it's desirable. And it's often because they used the naive solution to problems. Agile development philosophy states Refactor Mercilessly; I couldn't agree more, from experience. ...


5

Half-edges are usually used for many serious geometrical analysis and modification algorithms. You may find it more convenient to add a higher-level abstraction layer on top of this if you don't want to work with half-edges directly.


5

I would probably start with the following schema: Slot (ID, CharacterID, SlotID, ItemID) where Slot is the name of the table ID is the table's primary key CharacterID is a foreign key that points to the character SlotID is the slot's ID going from 1 to 64 (or 0 to 63, or whatever) ItemID is a foreign key that points to the item (ID of a specific weapon, ...


5

Various graph representations exist. Yours is an adjacency list with explicit vertices and implicit edges: Each vertex stores its adjacent vertices, each of which implies a directed edge to it. In the above, blue squares are vertex objects, arrows are references vertex A's list of vertices is [ B ] vertex B's list of vertices is [ A, C ] vertex C's list of ...


5

So this is basicaly topographical sorting problem. You have a graph, each node is a task that needs to be done, and some nodes depend on some other nodes (this is represented by an edge in the graph from depending node to the node it depends on). You want to do all the tasks, so you need to produce SOME ordering of the nodes that is topographicaly OK (the ...


5

This is very nice example of problem suited for A* algorithm. I will not go into details how to implement A* here as it has been done better before and this very easy to find, however this is how I would apply A* for your problem: As you can see, there is only a limited number of states that you can "move" to using single swap (14 for this case if I am not ...


5

Building on the answer from @congusbonus, if you are committed to using a single variable in an array as you have shown, you can define each combination in such a way that encodes each direction as a single bit in a bitmask: int T = 1; int L = 2; int B = 4; int R = 8: int TL = T | L; ... for (each room){ int exits = exitsList[this_room]; if (exits ...


5

First of all, consider if it is actually necessary to break down the world into units of storage. 32x16x32x16x16x16 = 67,108,864 blocks. When each block is a 2 byte integer representing the type-ID, your world is just 128MB of data. All but the most low-end platforms should be able to handle that in-memory. But let's assume that you already tried that and ...


Only top voted, non community-wiki answers of a minimum length are eligible