• Advertisement

King Mir

  • Content count

  • Joined

  • Last visited

Community Reputation

2491 Excellent

About King Mir

  • Rank
    Advanced Member

Personal Information

  • Interests
  1. That's true, but that is a different question: when to do a calculation client side or server side. And it's orthogonal. You can store the data on each user's machine, then send it to the server when a user connects. Or you can use other means to attempt to ensure the authenticity of the client application. In a 3d multi-player game it may be prohibitively slow or server intensive to make all calculations server side, so relying on client authenticity may be necessary, at least some of the time. For example, for things like obscured objects, generally you would want to rely on a graphics card to hide things outside the player view, instead of computing server side what the user can see, even though a hacked client could be made to see through walls (unless countermeasures are taken). That being said, using a database with the server has another advantage: it allows you to have multiple servers that talk to the same database, allowing more horizontal scaling. So even if some data is stored on the client, it probably still makes sense for the server to have a data store anyway.
  2. It's not quite true that data on the users computer can't be trusted. You can trust data that has been digitally signed by the server. For example, you could send a file to the server, have it verify it, and return a signature. When loading the game this signature can be verified. Verifying the signature can be done with a public key, and does necessarily not require communication with the server. Or, if the data you wish to save is duplicated between the client and server, you can simply have the server send the digital signature to be saved. When the client attempts to save, it will verify that the data it generates matches the signature and save both. It is important that both the client and server compute all save data in a deterministically identical way in this case.
  3. So boost has a "call_traits" library that solves this for setters and other function parameters. Essentially, what it does is special case for built in types, pointer types, etc, and assume a large object for all user provided class types. Like boost, you can provide a helper template for the best way to pass T to setters and other functions. Or you can use enable_if, other sfinae mechanisms, or template specialization to achieve the same thing. With getters, you kind of need to choose either const T & or T and be consistent because it will effect how the function can be used. I don't see any point in providing a set function if get returns a T &. If you do want a function that just returns a T &, consider making it operator *, and following the interface of std::optional.
  4. I haven't worked enough with cocos2d-x, but I expect that there's no "master" font unless you explicitly tell it to do something like that. This is easy enough to test though, so you'd probably get your answers quicker by testing than waiting for replies here; see what happens when you load two fonts in different order and see which one takes precedence for printing both shared and unshared characters. You might also be able to leverage native fonts on the machine instead of importing your own, especially for the limited case of the facebook login screen.
  5. So the problem with "not obsessing over making things exact" is that that could encourage micromanagement, because a micromanaging player can manage better than the ai in that case. I would prefer a system that just works for player and ai alike. That said, I'm not sure my current design squares up with that goal entirely; a player will be able to optimize by adjusting export priorities. With that in mind, I'm inclined to follow your original advice and use rational numbers.
  6. So if you're interested, here's the algorithm I'm using in some detail: For each city, A, (in an order that is complex to go into -- this isn't really a for loop but a recursive graph traversal) needs = demand of this city + all cities it exports to available = surplus of all importers added together For each city, B, that imports to A city_available = (production of B) - (all the previously calculated exports of B) if needs < available import ( (city_available / available) * needs ) resources else import (city_available) resources (Then calculate how much each city that city A exports to gets -- I haven't done this part yet) The outer order requires that cities have a priority of who they export to. For example a city would choose to export first to London, then everything that's left goes to Canterbury. But London is not going to prefer where its goods come from; demand is equal on all importers, and all of them end up with surplus if they can't pass it on their excess to Canterbury. Now I wish I could get rid of the need to have export priorities, but I'm pretty sure that would make the whole calculation a way too complex differential equation. As you can see, this takes an equal amount from each importer, even if it's a fractional amount; no remainder.
  7. The problem with that is, which cities do I take the remainder from? It can matter because it effects the resources available to be exported to other cities. I could add a priority to importers, but that would be adding interface complexity. In short, it would be different algorithm to do it that way. I don't plan to have transport delays; the timescale of the game is in years.
  8. Thanks for the feedback. Note do to limitations of how I'm compiling this, I can't use 64 bit integers. I can use 32 bit integers or doubles (which are precise up to 52 bits).
  9. I'm trying to find a good precise numeric solution for my problem. Background: I'm trying to create a trade simulation between cities. Each demands a certain amount of a resource and may have a certain number of importers cities that provide that resource. A city needs to take an equal fraction of each importer's resources, and the sum of the amounts taken must add up to the amount demanded. For example, if a city demands 2 bushels of grain, and has three importers, it will take 2/3 of the resources form each importer city, and the sum must add up to 2. Cities will always produce and demand an integer amount of goods, but a city may export to multiple places, so the amount of goods available may be a rational number. At no point are irrational numbers needed. Limitations: I'm working in C++ and emscripten. This means I cannot link any library to my project; I must include the whole source. For this reason, I'd prefer not to include any large library. I don't want to use boost. This is a closed source project, so I can't use anything GPL. Options: 1) Use floating point with an epsilon. But I'm not sure how to pick the right epsilon here. This reproach has the advantage of being fast and simple though. 2) Use fixed point. If I use scaling factor that's a multiple or several lowest factors, it may be precise. But I need to ensure that any numerator of my fractions is a factor of the scaling factor. I'm not sure if I can ensure this. But if a city imports from at most N cites, and the scaling factor is N!, maybe this could work? or some version of it? 3) Use rational numbers. This ensure that calculations are precise all around. If I implement this myself, this is the most complex option. The Ask: I'm wondering if anyone here has any suggestions as to which is the best option for my use case, and if there are any libraries I might be able to use.
  10. .data segment vs malloc/new

    This must be a relatively new thing. I haven't tried this in years, but there was a time where stack space had to be preallocated and going beyond the stack caused a crash. My information may be out of date. A dynamic stack really doesn't make much sense though as that is basically what the heap is or was. Maybe the line is being blurred?     Global variables are not on the stack. This means that they can indeed be arbitrarily large without compromising stack space. It's allocated in the ,data segment, not the stack.   However, the line is indeed blurred with respect to dynamic stacks. Compilers support segmented stacks, which are just that. This is often turned off by default, because it does have add performance cost to pushing and popping things from the stack.
  11. .data segment vs malloc/new

    I don't think it makes much of a difference from a performance perspective if your memory pool is global or on the heap. From an operating system perspective, both are just memory requested by the application, the only difference being when. Therefore I would use the heap because it allows you to have a more modular and reusable design. You also get the capability to ask for memory in blocks, so that your memory pool is aligned with the os page size on both ends, but this shouldn't matter very much, especially if your application isn't expected to page fault.
  12. I use pre by default for the reasons Hodgman described.   With regards to data dependency, it only applies if the result of the increment is used. So using increment at the end of a for loop does not use the result in an expression so there is no data dependency difference. However, if you are using the result of the operator, the the point is marginally valid. However I still don't find it too compelling for the following reasons: 1)the choice between pre and post increment can effect the readability of the algorithm, so this micro-optimization is less important than those considerations. 2) Rewriting code to avoid the use of preincrement may not actually reduce data dependency because the data dependency can be unavoidable. For example, moving a pre-increment to it's own line and making it a post increment does not reduce data dependency.   I'd say that avoiding data dependency is a good idea in designing algorithms in general but using post increment more misses the mark.
  13. Improving Readability & Simplicity

    I think of more importance than the implementation of a function is having a the interface of this function be clear. So the problem is less too many variables and more too many function arguments. An object the more elegant solution to that.   Now I do agree that you describe an elegant and extensible way to implement this attack function. Having the skill weights separated from the computation like that is a flexible design. But If I used it I would have a segment that converted the player object to a list at the start of the function.   With regards to indexing and accessing by names, what you usually want to do is not index, but iterate. A dictionary in python does allow you to do this by allowing you to iterate over all the keys to a dictionary. So an alternate design here is to have a dictionary/map of skills to player skill value(or an object as described above), and a dictionary of skills to weight in the combat calculation; and iterate over both. Something like this: skill_weights= {'combat': 0.20, 'weapon': 0.20, 'arm': 0.55} def attack(player, style):     total = 0.0     for skill in skill_weights.items():         total += player[skill] * weights[skill]     return int(total) (Warning: code for demonstration purposes only; I have not verified that it works or even parses)
  14. Issue with Construct2 and Firefox

    That sounds like a workaround too.   I actually have the opposite annoyance in my game in firefox, but I'm not using Constuct2: pressing ctrl+F fails to pop up the find menu. So it's definitely possible to prevent key-presses to be grabbed by the application and prevent firefox from picking them up for search and keyboard shortcuts. But I don't know how it's done or if it's possible with Construct2.
  15. Improving Readability & Simplicity

    I would just have an object like "PlayerSkills" or just "Player" that contains the list of skills for a particular character and is passed to the attack function. The contents of attack would be basically the same, but it'd clean up how you call it.   Basically, the strength of an attack is based on the style, and who's doing it, and this makes that much clearer. I'd recommend this over Albeth's solution, because of that clarity, but you can still his technique to simplify the implementation of your attack function, if useful.
  • Advertisement