• Advertisement

L. Spiro

  • Content count

  • Joined

  • Last visited

Community Reputation

25679 Excellent


About L. Spiro

  • Rank

Personal Information

  • Interests
  1. Gameplay Attack Speed and Delay

    This is not the way to implement pausing. Your game timer should be a 64-bit integer that is incremented by a given number of microseconds each frame. When paused, don't increment it. This means you have 2 timers, as the system timer can't be paused (and is mainly used for visual effects, or a timer for anything that can't be paused). In the context of an attack, the concept is the same: Don't update the timer if the game is paused. As I mentioned, these timers tick down towards 0 and expire when TIME <= 0. Since there will be many timers in the game for specific objects, the easiest way to avoid lots of special-case code and to reliably ensure that the whole scene pauses is to wrap the logical update in LogicUpdate( uint64_t _uiDelta ) or Tick( uint64_t _uiDelta ). While the game is paused, pass 0 for _uiDelta, and every timer in the scene will behave as expected. L. Spiro
  2. Gameplay Attack Speed and Delay

    Usually this is handled in the opposite direction. Set time until next attack is available. m_iMsUntilCanAttack = 1000000; // 1 second. Decrease value each frame. m_iMsUntilCanAttack -= iMicroSecondsThisFrame; Can attack if timer is 0 or below. bool CanAttack() const { return (m_iMsUntilCanAttack <= 0); } Since 0 is always the boundary you don't have to keep track of a 2nd data point, and since you always check against the numeric literal 0 the code should be faster. L. Spiro
  3. hand over your source code or you get no refund

    1: Could you stop putting spaces in front of every punctuation mark? Pretty sure that's one of those things everyone wants to say but no one wants to look like a jerk. There are no examples of spaces being before the punctuation mark in English, so there is no reason you should have ever picked up such a trait. 2: I haven't read everything, because you care more about making a fuss than solving problems. Thanks to your motivations, giant walls of text have been created instead of having pursued simple means of solving the problem, such as giving them the frigging project files. As was suggested you can strip the project down to something that is not your game but still has the problem. In the 15,000 days you spent writing the walls of text you could have done this by now. Or you could have written an NDA and had them sign it by now. Or you could have been more realistic about the entire situation and realized that the only thing that will actually happen if you send them your code is that they will find the bug and give you a fix. Whether or not your game will actually be profitable is a separate issue, but from your behavior you have given absolutely no one the impression that you are sitting on something worth stealing. With proper business sense, not only would you have not come off as an angsty kid who overvalues his or her product (again, speaking only about perceived value, not what value it may actually have), you would have quickly realized that when tech support asks you for investigative data, they are not aiming to rip you off. Any degree of common sense at all would have made it clear to you that companies that do this don't survive long. They can't run a business if their thinking is, "Oh boy, our product failed someone; let's steal his code." The fact that you think corporations are run by evil drug lords says more about you than anything else, and it's hard to have sympathy when you created all of this drama for nothing. It's not their fault you seem to think all business owners are evil. That's just something you made up on your own, just like putting spaces before punctuation marks. francoisdiy, what BagelBytes is doing is something of a practice run. He doesn't have the experience yet to make something you would want to use in production. L. Spiro
  4. It's literally the most important factor. I dropped out of high school, got no high school diploma or GED, no degree, and first applied to a company overseas with no prior work experience, but everything was in control because I had a portfolio. I don't want to say that a portfolio is a guarantee of a job, because being a programmer is a guarantee of a job. Programmers don't starve to death in ditches—that is not a thing. But it's far more helpful than a degree in the field of video games, where decisions are made based on merits, not papers. Your degree can't be worse than nothing at all because you can simply deny having it, which makes it at-worst exactly equal to nothing. Which puts you in the same boat as myself. Which means you have a portfolio or nothing. In this case I am not sure what the dilemma is. Why would "nothing" be more helpful than "a portfolio"? Pretty obvious what to do next, so get crackin'. L. Spiro
  5. Is there a doctor in the house?

    Button Obsession Sickness Syndrome, or BOSS. (I am not a doctor and arbitrarily chose words that would spell "BOSS".) L. Spiro
  6. Problem with sleep

    Thinking about algorithms or implementation details is the programmer version of a common reason for insomnia in which your mind is simply too active to get to sleep or to maintain sleep. I have horrible insomnia (at one point last week it was approaching 100 hours with only 10-16 hours of sleep), and so have strategies for fighting some of these problems. I tend not to program just before bed and instead engage in a long multi-hour wind-down involving video games (Super Smash for Wii U), chess, chat, and piano. It's good to have a variety of things you can do to pass a few hours before bed after programming. I am about to see a sleep specialist and will have better advice to share afterwards, but as grumpyOldDude points out it does tend to worsen with age. In my case sound sleep is almost impossible to obtain, regardless of what I do in the day, and it is impossible to say whether that was always going to be the case as I always naturally tended towards the nocturnal life, or if it got worse because I was unable to fix some tendency such as over-active mind earlier. L. Spiro
  7. New SEGA Genesis Game!

    http://www.bbc.com/news/av/technology-43001916/new-sega-mega-drive-game-made-on-90s-kit What are you waiting for, Nintendo to make one? I thought I would share this fun little project not just because it is neat but because he was one of my main coworkers when I lived in the UK. The place where he is doing the interview is the National Videogame Arcade where I played Super Smash Bros. for Wii U every Wednesday, so watching this brings back memories. Now I want to move back! He had mentioned this project a few times but I had never seen anything until now. It looks fun not just to play but to make. It really makes me wish I could have worked on some very retro games. I mean, it looks like a pain in the ass, but the fun kind of pain in the ass that feels very rewarding at the end, especially to have it on a real cartridge. Who else would like to see more of this kind of thing? Or even be part of this kind of thing? L. Spiro
  8. My implementation would be like what was done in Final Fantasy VII: Divide effects into a few broad groups (as you did with cold, electric, and explosion swords) and then define more detailed properties inside each group that weapons can have. I would use inheritance to implement the broad groups, as you can’t say how much they would have in common in terms of functionality or properties, and then use a data-driven model for the details inside each group. You can imagine all the attacks and effects in Final Fantasy VII. Whether simple sparks fly or a huge monster with a camera and scene animation comes could be handled by inheritance as broad groups that categorize the types of effects you want to implement. Then which sparks are shown or which monster is shown can be driven via data. You get a compromise between a data-driven approach and inheritance that should make even large numbers of attacks manageable. L. Spiro
  9. Undertale/ Doki Doki type system help

    Default behavior can be achieved in any number of ways. A simple way is to hard code logic such that, “If File.Found, do logic from file, else do hard-coded logic here.” This is not ideal, as you want your game data-driven and the code reusable, so the most common way is to check if an override file exists, do that logic if so, or do the logic in a non-deletable always-there default file. Those are basically the main 2 ways. From there, you can add as much icing on top by fancying up the system for replacing a default file. Allow these 2 to explain: Guy A: “I made my system so that if the file is in directory B, it uses that, otherwise it goes to the file in directory A.” Gal B: “I don’t want people messing with my files so I encrypted the files in folder A.” Guy A: “I don’t want people messing with them, so I encrypted them and hid them in a hard-to-find folder.” Gal B: “I don’t even want people to notice that the system exists, so I have my default files hidden and encrypted, and when the override file is lost I copy my default file into its place. This makes it look as if the file is always there, and my loading code only has to read the override folder, because it will always find either an override file or a default file that was copied into its place.” Guy A: “I like your eyes.” Gal B: “Here, you can have one.” *pop* L. Spiro
  10. How can I ever have time to finish my game?

    Since we are talking about shuffling things around to make time, do keep in mind that little things add up. These days I have to play Super Smash Bros. for Wii U at home at night, but previously I was able to get my daily injection by playing coworkers during lunch at the office, plus playing on Nintendo 3DS on the train to and from work. You can always switch things around as your interests change. Before I needed a daily injection of Super Smash Bros. *, I used train rides to play Brain Age: Train Your Brain in Minutes a Day!, or to practice Rubik's Cubes. Waste absolutely no time in your life. Since I will move back to Japan, I have to find daily time to practice Japanese and make sure I retain my level or improve, so I take Duolingo to the bathroom. I live near my office specifically to avoid long commutes. Driving to the office serves no purpose but to waste time. I live only 3.3 miles away, and I take Uber so I can spend the 10-minute drive (far too many red lights along the way) doing something besides wasting life looking at roads and signals. Let someone else handle that chore; I can make good use of those 10 minutes (although I am a bit restricted as some things, such as reading, give me migraines while riding in cars). Going somewhere on foot? If I tell you to run, it will only be the 55th time I give this advice. Going somewhere on foot means being unable to really focus on any other tasks, as you have to watch where you are going and avoid obstacles pod people. Being unable to focus on other tasks is Latin for "wasting time." There is no value in wasting time walking slowly to a destination. Always run. Gives more time to your day and keeps you more fit. Multitask when possible. I play piano while watching (or listening to) the daily news. I let YouTube run through the playlist of new uploads, and if a story is not interesting I play difficult songs that need my concentration, and when I am more interested in a story I play simpler songs such as Für Elise and mainly focus on the news. At the end, I've just spent 1 hour watching the news and playing piano, and my skill at piano increases more quickly because I train with mental weights. As I mentioned, I need to get lots of chess into a day, so I am mainly playing 1-day-per-move. I can take 5 minutes here-and-there through the day to make a move whenever I just have a moment. When I switched from 30-minute and 20-minute games to daily games, it served as an example of making an adjustment to suit your schedule. I don't have 20 minutes to sit and only play chess. Adjust your schedule in these ways, find ways to make small progress on many different things through the day, and then at night you will have much more time not doing all those things that you did here-and-there through the day and instead be able to focus on your project. It is extremely trivial to create time for things. L. Spiro
  11. How can I ever have time to finish my game?

    I have kids. Whew! These 2 running around the apartment, keeping me busy! Except for all that time I have for working on my projects, chess, drawing, piano, Cartoon Network, watching the news, nightly Super Smash Bros. for Wii U, showering, eating… L. Spiro
  12. How can I ever have time to finish my game?

    Any reason you can’t just work at home after working at work? That’s literally what I just stopped doing in order to write this post, and to what I will return when I am done with this post. Go to work, program, make money, go home at night, work on your game or personal project. What’s the issue? I don’t just work on my personal projects, I also practice piano for at least an hour daily (and piano classes on Tuesdays) plus practice chess for at least an hour daily, chat, write forum posts, plan and design my manga as time presents itself, and all while making good progress on my code daily. Really, I am not sure how this can be an issue. L. Spiro
  13. How To Convert double To float

    When dealing with normalized numbers, you just need to make the exponents the same value, which is just a matter of getting the real exponent value from the source by taking the exponent integer and applying the bias, then converting to the new set of bits with the new bias. If the exponents are the same, the rest of the number is converted just by shaving bits off the mantissa. You can round the number by adding the highest bit shaved off. My original implementation had the sign, exponent, and mantissa as separate numbers, so my implementation would have produced incorrect results when the mantissa was all F's and a 1 was added from the shaved bits. My mantissa would wrap to 0 but the exponent wouldn't have increased by 1 as it should. So now the problem with denormalized numbers can be made more general and refer instead to any case where the exponents in the source and destination are different (which will always be the case for denormalized numbers with different amounts of bits for the exponent). The most common case is with denormals, so I will go a bit into that. Denormalized numbers lose the implicit 1 on the mantissa. For normalized cases the mantissa always increases the value based off the exponent (it is always Exponent * [1, 1.999999...]) whereas for denormalized cases the number always decreases based off the exponent (Exponent * [0.999999..., 0]). You can't arrive at a general solution just with bit-shifting tricks now. You have to take the source number and the denormalized exponent bias on the destination to determine what mantissa value will best match the source value when multiplied. In other words, from a double to a float, ::pow( 2, -126 ) * X ≈ SrcValue, solve for X. Now you have one case generalized for values where the exponent in both numbers matches and another generalized way to handle denormalized cases, and then you patch for cases where the smallest normalized number is closer to the source number than the highest denormalized number, plus rounding into InF, and you are working with a single integer so that adding to the mantissa properly rolls up the exponent when necessary. Great! Now throw that all away and copy this guy's code: https://stackoverflow.com/a/3542975 He hard-coded it from 32-bit floats to 16-bit floats. I generalized it to go from 64-bit floats to anything else. It works properly in all cases, including going into InF and NaN, but doesn't allow specifying a rounding mode explicitly. I will have to add that later. L. Spiro
  14. How To Convert double To float

    Today I got it fully compliant with IEEE standards and full support for denormalized values. I created some intrinsics that allow you to specify the properties of floats so you can make any kind of float you want as long as no components are larger than in a 64-bit double (a limitation I might handle in the future). Here are some examples. as_float10( 1.0 / 3 ) 0.328125 (3EA80000h, 3FD5000000000000h) as_float11( 1.0 / 3 ) 0.33203125 (3EAA0000h, 3FD5400000000000h) as_float14( 1.0 / 3 ) 0.3330078125 (3EAA8000h, 3FD5500000000000h) as_float16( 1.0 / 3 ) 0.333251953125 (3EAAA000h, 3FD5540000000000h) as_float32( 1.0 / 3 ) 0.3333333432674407958984375 (3EAAAAABh, 3FD5555560000000h) as_float64( 1.0 / 3 ) 0.333333333333333314829616256247390992939472198486328125 (3EAAAAABh, 3FD5555555555555h) These are just shortcuts for the common formats you might encounter. For a custom type you can use the full instrinsic: as_float( 1, 7, 20, true, 1.0 / 3 ) // as_float( signBits, expBits, manBits, implicitMantissa, value ) 0.33333301544189453125 (3EAAAAA0h, 3FD5555400000000h) I will be adding more features to get properties of custom floats too. For example: as_float_max( 1, 7, 20, true ) // Gets the maximum value for the given type of float. as_float_min( 1, 7, 20, true ) // Gets the min non-0 value for the given type of float. as_float_min_n( 1, 7, 20, true ) // Gets the min non-0 normalized value for the given type of float. as_float_inf( 1, 7, 20, true ) // Etc. Also some options to display the components of floats separately (sign, exponent, and mantissa), and more features. L. Spiro
  15. How To Convert double To float

    You’ve missed the point. The IEEE standard would give me guidelines that I can generalize to any floating-point format of any combination of bits, as demonstrated above. In the example of PI I gave, you can see how it degraded in precision based on the number of bits I assigned to the exponent and mantissa. From double = 3.1415926535897931, to float = 3.1415927410125732, to float16 = 3.1406250000000000. It’s exactly this degradation that it is important to see and investigate for programmers in general, but heavily for graphics programmers. And again, note that I am not relying on a CPU cast, I am doing the cast manually, so I am not worried about what the compiler will cast etc., and I am not restricted in the floating-point type. In the last example I literally just invented a 38-bit float. That’s the whole point. I need to cast manually because I need to inspect float types that are not natively supported in C/C++. If I were to get clear documentation, or better yet pseudocode showing the micro-instruction process for converting a double to a float, I will be able to generalize it for my purposes to cast to anything. Every number I posted above actually came out of my converter, which I wrote just last night. Even the maximum float value came from my implementation rather than looking at FLT_MAX. The fact that my class generates the same value as FLT_MAX is just because my implementation is 100% correct for normalized numbers. That part is a completely-solved area. I want to look at standards and example implementations so that I can be confident I’ve handled all edge cases specifically dealing with denormalized numbers. L. Spiro
  • Advertisement