Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 28 Jun 2000
Offline Last Active Yesterday, 06:00 PM

#5264121 Best route to take for automatically going through a program

Posted by Wyrframe on Yesterday, 11:10 AM

SikuliX is a scriptable system that lets you automate desktop interaction using image-recognition and OCR, so you can cope with unpredictable positions of windows and GUI elements.




It's ideal for automating simple GUI processes when AutoHotKey doesn't suffice.

#5263015 Random errors in Release builds

Posted by Wyrframe on 21 November 2015 - 12:25 PM

Alundra: He had the if clauses to guard against unused bone indices. However, profiling would indicate if it would be more performant to simply include an "identity" bone matrix at a specified index and use that instead of a sentinel value like -1.


Ryder052: What do you mean, "any leads"? That's a small piece of a shader program. We can see two variables initialized there, and can't see where the other 3-7 are or are not initialized. Not much we can do to help with that little information. Why do you think that piece of code is to blame? If you do know that's where things are going wrong, just walk through the possibilities and check them. Can input.weights be uninitialized? Can the indices be uninitialized?

#5258921 Randomness (enemies, drops, items, etc) getting messy

Posted by Wyrframe on 24 October 2015 - 10:00 PM

Sounds like you have three problems here, and you've already half-solved one of them:

 * Given a location, what approximate difficulty of mob should be spawned?

 * Given a difficulty, what specific mob should be spawned?

 * Given a mob, and maybe given a difficulty, how many units should be spawned and what should their stats be?


The first you've assigned as the responsibility of some kind of map search, a "minimum distance to home" metric apparently.


The second, you say you'd like to obey a Normal aka Gaussian Distibution curve centered on the difficulty level. The most correct ways to do this are quite complex, but there is a shortcut that's often "good enough". Generate a random number in [0,1) then square it, and then on a coin-flip negate it. This will give you a number in [-1,+1] with a 50% chance of being in the +/-0.25 range, a 70% chance of being in the +/-0.5 range, and an 86% chance of being in the +/-0.75 range. Then simply multiply by the half-width of the difficulty range you want (i.e. on a 26-point scale where you want +/- 4 enemies from the "target" difficulty, 4/26=0.15), and then add the desired target difficulty metric.


That's all just the number crunching that you need to put into your Factory.GetRandomBaddieType(Number) method, though. Your third problem lies inside the GameObjectManager.MakeBaddie(...) method, and I'd need to know more about the way you've created your enemy representations to suggest design patterns for creating them. But the code you've shown us thus far looks like it's well-enough designed... so where the the maintenance nightmare that you're having?

#5256299 [Unity] Arrays

Posted by Wyrframe on 08 October 2015 - 06:03 PM

Adehm; you're misunderstanding how indices work, in contrast to how array allocation works.


public int[,] HOME = new int[4, 1];


This gives you an array of 1 by 4 cells. It's your choice to call those columns and rows or rows and columns.


But arrays are what is called "0-indexed." A one-dimensional array of size 5 (say, int[] list = new int[5]) has valid indexes 0 and 1 and 2 and 3 and 4; five total cells, starting at cell number zero. Similarly, a two-dimensional array of size 4,1 has valid indexes 0,0 and 1,0 and 2,0 and 3,0... and that's it. To store two "fields" per "row", you want new int[4,2], and index them at R,0 and R,1.

#5256298 Safe problem in scene Manager about root array + linear array

Posted by Wyrframe on 08 October 2015 - 05:47 PM

You could solve it using a change-if-needed paradigm.


SceneManager::AddActorInRoot(IActor &actor) checks if the actor is already a member of the root list. If it is not, then it adds it to the list and calls IActor::SetParent(this).


SceneManager::RemoveActorFromRoot(IActor &actor) checks if the actor is a member of the root list. If it is not, then we do nothing. Otherwise, we remove it from the list and call IActor::SetParent(null).


Actor::SetParent(SceneManager* new_parent) first checks if the new parent is the same as its current parent. If it is, we return without doing anything. If its current_parent is not null, we call current_parent->RemoveActorFromRoot(*this), then sets current_parent to the new_parent. Then if the new parent is not null, call new_parent->AddActorToRoot(*this).



The loop is not infinite because we recurse only if the requested final state is not the current state. We can call from either end (SetParent or AddActorInRoot/RemoveActorFromRoot) first because either path ends up calling the other if necessary. And as a Java programmer looking back on my C++ days, I strongly suggest using a reference parameter instead of a pointer wherever taking a null pointer as an argument would be 100% unacceptable.

#5255595 Mouse over sprite detection with zoom

Posted by Wyrframe on 04 October 2015 - 10:14 PM

You're doing a few things wonky; first, you're mixing world-space and screen-space coordinates all over the place. Second, on lines 42-45 (the condition of the hit-test if statement), you're treating X,Y as midpoints of your object, even though lines 39-40 are clearly trying to make X,Y be the top-left coordinates. Because of this, objects are treated as being "hit" if the mouse is within 20 units above and/or left of the square drawn for each object, as well as within the object's actual drawn bounds.


To fix these:


When drawing, transform object coordinates from world space (their actual X,Y,size, etc) to screen space (their on-screen position, size, etc); then draw the screen-space object.


When hit-testing, transform the screen-space mouse coordinates into a world space sample point coordinate, and then hit-test against objects strictly in world space using that coordinate.


Finally, choose whether the objects' X,Y are their top-left or their center, and then be consistent. To test a point for being inside a square with a top-left at X,Y, you want to test (pt.x >= obj.x && pt.y >= obj.y && pt.x < obj.x+size && pt.y < obj.y+size).

#5253053 Shipping Simulation ( Dijkstra / Floyd-Warshall / ? )

Posted by Wyrframe on 19 September 2015 - 10:23 AM

How I learned to stop worrying (about the relative size inefficiency) and love Dijkstra maps:



That's the other thing about Dijkstra's algorithm. You don't need to have one global destination; if you have multiple destinations, then all points will simply pathfind to their local minima. Even if your minima are of different values, it still works out. It's expensive to store if you have absolutely massive maps, but if they're only moderate-sized maps, the space inefficiency more than makes up for the fact that it supports any number of actors using it.

#5252975 Shipping Simulation ( Dijkstra / Floyd-Warshall / ? )

Posted by Wyrframe on 18 September 2015 - 07:38 PM

Why are you classifying Dijkstra's as a single-pair search algorith? In my experience, Djikstra's is usually used to find the optimal path from all locations to a minimal-cost destination, by exploring a search space which you then "roll downhill" on.


1. At the destination D, set the cost of the destination C(D) to zero. Set the cost of all other locations to positive infinity (or some other arbitrarily excessive value).

2. Set up the edge cost function W(A,B), which gives the non-negative cost of traversing the edge directly from A to B. Directed edges work fine. Zero-cost edges are allowed.

3. For all locations L, let their new cost C'(L) be the lowest value among their current C(L) or among all adjacent locations A, C(A)+W(L,A).

4. Repeat (3) until no new lowest costs are discovered during an iteration.


To use the data, to go from any location X towards the destination D, traverse the edge from X to the lowest C(Y) among Y adjacent to X (aka "roll downhill"). This algorithm is tolerant of the data changing in-between steps. All locations in disconnected subgraphs that do not include D will have a cost of positive infinity.


When you dirty your edge costs, start re-calculating the costs to each destination. You can do one destination per tick, if you like. The strict Djikstra algorithm doesn't give you usable data in-between step-3 iterations, but neither does A*, so what the hell.

#5250839 Recreating some NES limitations

Posted by Wyrframe on 06 September 2015 - 10:16 AM

Oh, drat. Sorry, yes; I forgot there is a universal "background" palette entry, shared by all tiles, and generally output "outside" of the rasterized portion of the screen.


If the background layer is always behind the sprite layer, then how do you get this: (VIDEO) Or the mist in the Faxanadu video linked above?  Or the drills that carve through the floor and ceiling in Mega Man 2?  If that isn't drawing the background in front of the sprites, then how are they achieving those visuals?

As I understand it, they're placing sprites containing those background tiles overtop of the sprites which they want to look like are behind the tilemap. So, back to front, tilemap -> mobile sprite -> background impostor sprite.

#5250704 Recreating some NES limitations

Posted by Wyrframe on 05 September 2015 - 11:55 AM

I just realized I may be making a false assumption about the nature of tilesets, so I should confirm. [...]

In approximate order...

 * Yes, because you have a mapper that can virtually map a few 1KB pages of ROM to the tileset/sprite memory areas, you can have several parts to your tileset, but you are fixed in what each part contains. If your tilesets have visual overlap, they'll have duplication.

 * If you're using RAM for tilesets, you get a span of RAM that you get to manage and populate yourself. And although you have a DMA-like block copy mechanism, you only have 2100-odd clock cycles to repopulate that RAM in if you want to completely change it up.

 * I think once you choose ROM, mapped ROM, or RAM for a particular section of the address space, that decision is baked. No mappers that will let you page your choice of ROM or RAM to a particular address later.

 * One of the benefits of RAM tile memory is that you can change it between vblanks. So you can have parallax-like scrolling effects by overwriting a particular tile with other tiles from ROM, animating a map tile by replacing the tile graphic it uses.

 * On the NES, tiles are always behind all sprites, and are always 4-colour opaque (one colour of which is always black is shared among the entire tilemap). Sprites are rasterized in order on a given scanline, and IIRC always have colour zero transparent (no 4-colour opaque sprites).




And how many tiles is a 1KB page?

4 values = 2 bits per pixel, 8x8 pixels, 2*8*8 yields 128 bits per tile, 128/8 yields 16 bytes per tile; 1024 bytes allows 64 tiles.


Yes, they were usually written in raw assembly; IIRC, that stayed true well into the PS1/N64 era. Don't try to fit your C# code into a size constraint. If you're not programming in assembly, don't force yourself to meet the ROM size limitations of the day. Even if this (https://www.youtube.com/watch?v=jB0vBmiTr6o) and this (https://www.youtube.com/watch?v=plF1nqkcivg) are each 4kB Win32 EXEs.



EDIT: Forgot about the universal background colour, and stripped out those obtrusive video embeds, I only wanted to make links.

#5249914 Parameter-Based Argument Sending

Posted by Wyrframe on 31 August 2015 - 09:16 AM

Consider the impact of this system on situations such as...


 * Recursion: you often have to temporarily save copies of fields into local variables, which means copying them to the stack... where they would have been if you passed them in traditionally.


 * Mutual calls: if a method using that structure has to call another, it has to either save some fields to locals, or rewrite the structure entirely for the second call.


 * Parallel processing: ohgodwhy


 * Change management: if the arguments to a function change, you can't merely find all references to that function and update them; the actual code to be affected will be spread throughout various bodies leading up to the calls.



What you've laid out is pretty normal for extremely embedded systems where you have a hardware stack (which can only hold return addresses) or otherwise highly limited stack memory (e.g. only dozens to hundreds of bytes of stack space, instead of thousands to millions)... but those kinds of systems' software is usually developed under very rigid change controls, where ideally 100% of the program is documented and planned out and constraint-optimized, before even a single line of code is written.

#5248771 Visual Studio 2013 raw string support missing

Posted by Wyrframe on 25 August 2015 - 08:52 AM

The parentheses are a required part of the syntax, yes.




The format of a raw string is uppercase R, doublequote, an identifier for confirming the end of the raw string (empty-string is an acceptable identifier), open paren, and then content. To end the content: close-paren, identifier again, doublequote. So, R"stringterminate()))blahb\"lah))stringterminate" yields the content )))blahb\"lah). Think of it as being able to customize the ]]> terminator of CDATA.

#5246255 Why should I ever program a game again?

Posted by Wyrframe on 13 August 2015 - 11:01 AM

since the invention of the PC, games have evolved from text mode graphics and pc speaker sounds
And the only thing that prevented people from playing games on punch-card machines was the tangible, measurable, physical cost of performing I/O. :D

#5243108 TOO SLOW; TOO ERRONEOUS - HELP with Building a Procedural Road System Using t...

Posted by Wyrframe on 27 July 2015 - 09:22 PM

Look up algorithms which perform Voronoi tesselations of a field of points, and/or look up algorithms for a Delaunay tesselation and then take the mode of the produced graph (viz; replace polygons with vertices at their midpoints, and replace vertices with polygons which have a perimeter formed by connecting the new vertices created from their former adjacent vertices).


Looks like you have more intersections than specified points, so add some extra points to your data with random midpoint-displacement subdivision or something before feeding it to the tesselator.

#5243096 Is Google Play Game Services or Apple Game Center worth it?

Posted by Wyrframe on 27 July 2015 - 07:51 PM

On the flip side, I'd like to voice the directly conflicting opinion. If your game requires Google Play Games integration (i.e. at the "Sign In to Google Play" popup, the Cancel button returns me to the launcher or re-shows the popup, instead of letting me through to the game's main menu), I'm uninstalling it immediately and leaving a zero-star review. A developer of a game I haven't even gotten to try playing yet does not have the right to datamine my account, log my access, and make cutesy Facebook-style bullshit show up in my G+ feed before I have even evaluated whether I will continue playing the game.


On a related note, if your game requires any permission stronger than mere "Internet Access", you're never even getting installed. You don't need full access to my SD card storage, you don't need location services, you don't need phone state and caller ID, you don't need Manage Accounts. The crap people want to get away with for even the simplest software these days is ridiculous.