frob

Moderators
  • Content count

    10888
  • Joined

  • Last visited

  • Days Won

    6

frob last won the day on October 9

frob had the most liked content!

Community Reputation

45008 Excellent

1 Follower

About frob

  • Rank
    Moderator - Mobile & Console Development

Personal Information

  1. That is because as others point out, it is syntactic sugar over the same issue. The issue is mutable shared states. Mixing mutable shared state in any sufficiently large system is going to face issues with it. Two threads are going to modify it, or unrelated systems will fight over it, or similar. They introduce hidden coupling, introduce hidden dependencies, complicate or break tools like dependency injection, block extension, and cause many other issues. The Singleton pattern (which means there can be only one) is that issue and more. In addition to shared mutable state it also creates unrealistic and improbable demands that a single instance is the only one that will ever be wanted, that no code will ever want to replace it, or extend the behavior, or replace the behavior, or provide either alternate or missing behavior, or many other conditions besides. It is well-covered as being "evil". As for the shared mutable states in C and C++, there are a few that cannot be removed. They are holdovers from decades ago (probably long before you were born) when parallel processing was rare. There are the global streams (stdin, stdout, stderr) and their associated global locale; they have c++ class equivalents but they remain the three streams. These cannot be designed out of the language nor is there a good way to remove them universally, so they are here to stay. Some shared mutable states remain because removing them would break too much code, but they have alternates for new code to use. There are strerror(), strtok(), and asctime() functions that all have static buffers internally. There are a few oldcharacter conversion functions between multibyte and wide characters that have shared state, such as wctomb(), mbtowc(), wcsrtomb(), and mbsrtowc(). There are some math functions like the gamma() family and rand() family that rely on internal state. All of these have alternate versions available that do not rely on shared mutable state. And a few historically were shared but have been corrected, such as the errno codes from system libraries. In some cases there were rather extensive system library changes to support it, but the change was still made. There are some on hardware as well. Floating point control is often fought-over between libraries. Setting the precision, denormalization options, error handling, and floating point exception resolution are commonly troublesome. Floating point rounding modes (even/nearest, up, down, and toward zero) can also lead to some 'gotcha' bugs. This is common to all languages. You can mask it in various ways, including hiding in namespaces or wrapping on functions that modify hidden variables, but ultimately the underlying problem remains. Even in functional languages, where there is tremendous effort made by the language designers to avoid stateful conditions in general, can still occasionally be stung by unintended shared mutable state. As programs get larger and systems grow they will nearly always have some mutable shared states since there are times when the engineering effort required to avoid it is greater than the project is willing to bear, but that should be weighed as an intentional choice to implement the shared state, and mitigated through policies such as ensuring modification only happens at specific times, or by specific systems, or in specific manners. These rules can be put in place in many ways, including having functions that modify a static variable that is kept out of visible scope (such as within an anonymous namespace or as a static variable within a file) but they remain an implementation of a shared mutable state.
  2. I'm guessing the reason you don't see them is because you don't see many varieties of code. This is because static objects are almost always the wrong choice. That's not referring to static constants, where the compiler will typically use the value directly to simplify the executed code. Outside of that use, a static value or a global value is nearly always a bug or design defect. Usually in the handful of cases where they are useful they still are not ideal from a conceptual standpoint, but instead they are an informed decision where the developers decide the advantage in their specific situation is worth the added cognitive effort of adding the shared state. I've never heard an argument that it wasn't, apart from the fact that globals and shared state tend to be 'evil'. A globally accessed pointer, or perhaps a restricted access pointer with static linkage, can work fine with this scenario, assuming rules are followed to ensure consistency and access through safe patterns. Imagine a logging framework providing a bunch of functions that take an optional logger. It can have a pointer to an instance that is the default instance, and that default instance can be swapped out. Then a set of freestanding functions can call that instance. Thus you have functions that exist on an object allowing you to use your own: mylog->Info("This happened (%d)",thing.id); And you have the namespace-wrapped versions using the default: logger::Info("This happened (%d)",thing.id); That version can use a namespace-constrained pointer, perhaps logger::defaultInstance or something, and the free-floating Info function could pass the call directly on to the defaultInstance version if the pointer is valid. This in turn makes the tradeoff as mentioned above, the implementer decided the convenience was more important that the extra hidden dependency and the burden of ensuring validity of that hidden dependency. There must be assurances that the defaultInstance pointer has a sane value and is only swapped out at well-defined times. Because you still have a static variable, you still have a shared mutable state. That should be avoided in general, so it makes for a bad suggestion. It is less bad that other bad practices, but that doesn't make it a good practice. Shared mutable state brings with it a host of issues. It can change behind your back, at any time, for reasons you cannot predict. The risk can be reduced through human-enforced rules about how and when it is used, what the values must be at certain times, but ultimately there can be no enforcement. In any non-trivial application this will eventually bite you as someone somewhere changes the value. In addition to being unable to create more than one, the Singleton pattern also frequently invokes shared mutable state among its assorted issues. Since this isn't supposed to be people bashing on Singletons since we all know the pattern is seriously flawed, that's probably enough there.
  3. What is the best OS and IDE for game dev?

    Some is driven by preferences, some is driven by necessity. If you're developing for Windows or Linux or Mac OS X, you'll need that. If you require tools that are only for one system, you'll need that. You mention working on Unreal. That means you need either Windows or Mac. Linux is not a supported option. In general the platforms you use are a reflection of the environments. If you're going to be doing extensive server work and you typically work in headless environments (no computer screens) then you will be far more likely use a Unix-based environment. Windows is the general "what everybody uses" environment. Apple's ecosystems are Unix-based for the programmers and technical folk, and they're beautiful and often used by visual folk, but it seems the rank-and-file people aren't comfortable with them. In short, there is no "best". If the systems are compatible for the task at hand, it becomes a matter of personal preference.
  4. Putting those together: Does {an online market that lets individuals buy and sell resources} encourage {people to sell mostly-complete products used for asset flipping}? I get that they're not the cause, they didn't invent asset flips, but I still think it's worth discussing their role in it. On the general level, the open-to-anybody marketplace will always have this type of thing. No matter who runs the market, no matter how strictly they attempt to regulate it, there are always people who will try to exploit. In that regard I do think the organizers deserve a pass. On this market specifically, what would you have Unity or the market's community do differently? What exact policy would you want to put in place that would solve the problem you see without incurring serious collateral damage? Any wording or policies I think of cover not just the mildly-problematic flipping issues, but also a wide swath of useful materials.
  5. I don't think they're the cause of the issue. Certainly they make it easier for people to sell their items and for people to buy the items, but that doesn't make them liable for how the items are used. They do a good job of making it easy for buyers and sellers to come together, and that's a valuable service. There have always been people out there who bring together the minimum parts they can, make a slapdash product, and attempt to profit from that. The market happens to make it easier to get better components for the slapdash product, but they aren't the cause of the behavior. That behavior has been around for all recorded history. It is literally among the oldest recorded actions of humanity. Given enough people there will always be some who attempt to make a quick buck this way.
  6. Usually it is through error codes and status codes. That is the model used since the 1950s, and works well enough. Basically the same as C libraries. Consider how if reading a file fails. You call fread() to collect a bunch of bytes. But you cannot blindly assume all the bytes have been read, instead, programmers are expected to always check that the number of bytes read equals the number of bytes you expected. Or consider such as network socket programming. You call connect() to initiate a connection. The only way the connection is valid is if it returns a status of 0. There are plenty of other status codes, connection was refused, address not reachable, connection already in progress, no route to network, and they are all possible. Programmers are expected to check that the connection was actually established (rather than one of the other status codes) before using the connection endpoint. Other calls will return a pointer, or will fill a structure and return a count of the valid items in the structure, or will otherwise pass along the situation. In these cases a zero count or a null pointer are both valid options, and the code is expected to deal with that as an appropriate response. Programmers in different paradigms, such as where having a process die is acceptable because a parent process can intercept it to realize it has failed, will often ignore such return codes and rely on the eventual crash to signal the situation. C++17 introduced an attribute for that, [[nodiscard]], that can help if you are using this paradigm. When used, the compiler recognizes the result code is something the programmer should be relying on, and the compiler should warn that the result has been discarded instead of processed.
  7. Excellently worded. In games -- and in particular on the big three game consoles -- errors are not considered exceptional. That is, the fact that things fail is not an exceptional state, it is an expected value. It is expected that people can pop out a disk, it is expected that networks will fail, it is expected that controllers will be disconnected, it is expected that writing temporary files will fail. The same thing in constructors. Within this world view it is expected that memory allocations can fail, that resource allocations can fail, that resources may not be opened. So for most code in such systems, the constructors do not allocate resources or do other operations that fail, they are slightly glorified versions of the code obj = malloc( sizeof(object)); memcpy( obj, defultvalues, 1); That is, all they do is create an instance and set a few default values without doing any major work. They don't do any work that can fail. In other paradigms this is not true. I've done development inside and outside the industry, including sever work where exceptions are the preferred method for handling things. In that paradigm responses are built, and if there are problems at any step the whole thing is discarded and a different result is returned to the user. Horses for courses, or whatever the proverb is in your area.
  8. It is a great learning exercise, and I agree there is much value to it if this is something you want to learn. Fair enough. Split it however you want. Sounds like you have a reasonable set of tools. As you increase in skills you'll want better tools, but it doesn't take much to build what you described. It has been a few years, but I made several similar projects back in my high school and college days using simple text editors and command-line compilers. It can still be done today. The best question to ask now is: What is stopping me now? If nothing is stopping you now, then get to work! If something is stopping you, identify that one thing and get it resolved. Then once it is resolved, get back to work. So instead of asking if you have the best tools, let's turn it back on you. What is stopping you from making progress on the project? Why aren't you typing away at your solution right now?
  9. "Windows protected your PC"

    It is not really when you consider the typical user out there. In fact, it is a very good behavior for the billions of people who aren't software developers. Most people only run a small number of programs. Those programs have many installs. The programs are easily identified by fingerprint and can be trivially whitelisted. It is rare for most people to run the unsigned executables that have no other users, no known fingerprints, and yet require extensive system integration like games have. For most people when they encounter the situation it truly is a software threat. That doesn't mean the dialog isn't bothersome, but when you look at the billions of people globally who use Windows, and you look at the thousands of game developers globally who are bothered by the dialog, the attempt to save them from themselves is quite sane and rational. Bypassing the warning is easy enough, requiring two clicks. People who are running games made by individuals are the same people who are technically savvy enough to push the 'more info' button and the 'proceed' button. And if your software triggers the alert and you really are releasing it to the public, it is quite easy to satisfy the requirements to get whitelisted.
  10. Does violence stem from video games

    I think that's mostly confirmation bias. Someone does something horrific. People want to see what is different about them, what triggered the horrific behavior. They look at a long list of things, and focus on the things that they personally think are abnormal or problematic. When they find the things they think are atypical, since the person who committed the horrific actions also participated in that thing perceived as bad, the person mentally affirms that the two are linked. The common motivations I see for most of the mass shootings tend to be a long series of abuses and harassment. The link above to Winnenden lists that as among the major motives: Bullying, personal stress, depression. That short list is common to many mass shootings. Abuses at the workplace that are not addressed by management, abuses by classmates that are not addressed by administrators, abuses by people who are outside their group that are not addressed through proper channels. Their tormentors tend to be the preferred targets. It certainly is not all mass shootings, there are other motives for some, but it is a common motive. The links to studies showing people don't feel violent after playing violent games were on the last page. People generally feel competitive feelings, the same as they would after any other competitive match, from an intense football game, an intense tennis game, to an intense chess match. All tend to carry on feelings of victory or of defeat, not of violence. Many people are surprised to learn violent crime rates have been going down for twenty five years. Looking at a per-capita basis, 2016 continued the downward trend being the lowest year on the trend line that has been dropping since 1991. 2014 was 2946, 2015 was 2885, 2016 was 2847. Violent games have become more and more common since the early 1990s, and violent crime among people who play games (nearly everybody) has been on a steady downward trend since the same timeline. There are far too many variables to put it on any one thing, but that trend line has a near-perfect correlation to the availability of violent games. If there were a positive correlation then there should have been an increase on violence as violent games became widespread, with notable bumps in violent crime after violent games were released. Fine-grained studies show instead there tend to be small dips in crime after major games are released, although even those are hard to show anything beyond correlation which could be due to many factors. So getting back, YES games will influence a person's behavior. But NO, violent games will not cause or induce violent behavior or violent crime, as shown by several studies and by crime statistics.
  11. Graph to terrain conversion

    What do you need in a terrain? Do you want a regular grid, as those are used in many engines, or do you want an irregular mesh? A TIN may work better for some purposes as they can potentially be smaller and easier to work with than a full grid mesh. If you're looking to merge them into a regular grid, are you able render each area as a polygon on a plane? That kind of rasterization is probably easier than iterating over every point with each point requiring a new search of the graph. Even if you had to render each of your twenty or so layers individually as polygon meshes and then merge them as a single linear pass, that would still likely be less processing work than searching the graph for every pixel in the image.
  12. Those are not easy games to build, and the Unity engine is not designed to work like that out of the box. Unity allows creation of arbitrary objects, and allows you to build and clone your own objects through a system of what they call "prefab" objects. Unity normally works with freeform placement, so all the work of creating wall-type objects, and the work of snapping objects to a regular grid, keeping that grid on the ground, and any other placement rules such as not interfering with other object's footprints would all be handled through your own game code. I don't know of any specific versions, but I imagine the Unity store has several libraries that people have written for that type of thing. A few quick searches using Google show many tutorials and demos of working with grids generally, but I don't see any that cover exactly what you are looking for. If you can find one of those as an existing tool on the store, that may save you some work. You will probably need to modify it, tweak it around a bit, but it can give you a start. As for what to learn if you intend to work like that, the first thing you'll need is how to work with the math of the grid world. If you aren't already comfortable with it, a grid can be put together fairly easy using modulus math (the % operator), but working at odd scales irregular placement outside the grid can be more tricky. Creating objects will mean understanding how to work with prefabs. You'll want to read up on tutorials for creating prefabs and spawning prefabs through code. There are lots of tutorials on that. As you'll want them on the ground layer, you'll want to find some tutorials about working with the ground. Many of the prefab tutorials have notes about using a raycast to find the height of the ground and then placing it at that height. It can have trouble if your ground is not flat, so learning to modify your height grid programatically should be on your list if ground is not flat. You'll note in the first two incarnations of The Sims players were forced to build a ground slab before placing walls. After that, from your description you'll need to learn about rubber band selection or rectangle area selection so you can pick the items based on your mouse areas while playing in game. Again, there seem to be plenty of tutorials on that. And assuming you want all this to happen in game as part of an in-game editor saving the world designs (rather than in the Unity editor where you modify your program's structure) you'll need to learn all about serialization or save/load systems. If you are going for something like The Sims, that game does a tremendous amount of work to hide the differences between the logical world in data and the visual world that you see. Game objects in logic are merged together. Many things are hidden in various ways. For example, you can only see inside the buildings on your lot, and only the height level you are currently on. When it comes to rendering many objects have their models and textures fused together so that instead of rendering hundreds of tiny decorations the game actually renders a few large irregularly-shaped objects. You generally don't see it as a player, and as a developer it is typically not seen unless working in the code directly related to editing the sims or editing the snap-together items in the world, such as countertops and walls. I hope that gives you some options for places to look.
  13. Initializer lists are still the best option when values come in as parameters. The initializer list will be used instead of the default values. Really all of this is to avoid the double initialization which you'd see with zero initialization. The point is to avoid multiple unused assignments. If you can assign it to the correct value the first time --- which might not be zero --- then do so. That's better than assigning it to zero the first time, then assigning it to another value the line afterword. On the flip side, that also means not bothering to set values if you know they'll never be read, such as not bothering to zero the contents of an empty memory buffer while you've got a marker saying zero bytes are used. Initialize them to whatever you need them to be, but don't worry TOO much if you make a duplicate assignment or if there is duplication between the initialization list and the constructor body. For most of these types the cost is a fraction of a nanosecond. Not quite zero and something you should think about when writing code, but there are much bigger issues to address.
  14. Does violence stem from video games

    Sure, health is arbitrary. (Also I understand the psychology folks prefer to call it compulsive, rather than addictive. Some definitions of addiction require chemical components, but any behavior can become compulsive where the person feels strong urges toward or against it.) For physical health, you might argue that being unable to run a 5K is unhealthy as healthy people can typically run it, or that being unable to walk a 5K is unhealthy, or that being unable to walk 200 meters is unhealthy. The line is arbitrary, although I doubt many people would say someone who struggles to stand due to extreme weight would be at a healthy weight. Even so, I'm sure as an arbitrary line someone could say that if they're not completely dead it must be an acceptable weight. For mental and emotional health, it is similarly arbitrary. When a person has difficulty forming interpersonal relationships, difficulty relating to other people, difficulty interacting with people on anything beyond the most basic levels, there are degrees of it being unhealthy. I've known people who were unable to hold a job or to really do anything that didn't fit the flights of fantasy from the books they were constantly reading. I've also known people who were constantly in romance novels, and who had given up on real life relationships because none could compete with the dramatically scripted highly romantic plots in the books. I'd consider both to be unhealthy, but they're not dead, so who knows where someone else would place the arbitrary line. I'd put the arbitrary line at the point where it begins to interfere with 'normal life' or disrupt someone from doing the activities they wish, although that too is arbitrary. If you are unable (or unwilling due to compulsion) to do what most people are able to do, it is unhealthy.
  15. What laptop should I buy as a developer?

    In general, any modern laptop will have sufficient hardware power for you. All the major tools run just fine on all the mainstream computers manufactured within the past decade. You do not need to spend thousands of dollars on the machine, you can use a low-budget or used computer if those are the funds you have. Consider whatever type of game you'll be playing on your new machine. The game you make as an individual will be far less sophisticated. Even running the fancy build tools and developments you will still not tax your equipment to the same degree. Regarding the choice of what software to run on the system, that's up to you. Since you mention phones, if you're seriously looking to target the Apple ecosystem you'll likely want the macbook for that since it is required for the official build tools. However, if you really want a Windows box because it will be your main computer and you want to run all the latest games, do that instead.