—    —  Home

   jamesprimate on February 21, 2014, 05:20:39 AM:

Found a nice post-KS interview with James
http://thebitpulse.com/2014/02/project-rain-world-qa-james-primate-on-the-weight-of-expectation/

@Joar/James - Will you be doing a postmortem on the campaign?
Thanks for the link, it was a great read!
A postmortem would be awesome!

Thanks! Reading through it, Im actually surprised how lucid it was considering I wrote it up at 5am after being awake for like 2 days haha.

Hadn't considered a postmortem. I'm usually pretty skeptical of them because success/failure all depends on sooooo many factors, trying to point to this or that reason you think caused something just seems like a guessing game to me. Then you'll have other people planning kickstarters reading it and using those arbitrary opinions in their own kickstarters because "it worked for Rain World". That's bad because even if the self-analysis were accurate, there is no reason the same things would work under different circumstances, or that other things wouldn't work better. We're all just leaves in the wind.

But that said, if anyone has any specific questions I'd be more than happy to offer some opinions based on my (admittedly limited) experience Toast Left





   jamesprimate on February 21, 2014, 09:07:48 AM:

Ok, I'll do my best!

Since Juan is actively engaged in a Kickstarter right now (good luck!), I'll focus on his first:

One thing that I can't deny is that Rain World benefited a hugely from media exposure. And while this may have been exaggerated to a degree by the relative lack of other games on kickstarter at the time (AND as stated, the fact that many were already familiar with the game), a great deal of it was cultivated through simple hard work of media outreach.

For the launch and major updates we sent out about 350 (short, courteous, content-focused) emails to every game-related site/magazine/journalist/blogger we could find, then kept in contact with them throughout the campaign. Further, we made sure that everything we sent out was "worthy of coverage", with new videos showing off major aspects of gameplay, screenshots, gifs, and in-depth discussion about content and things like that; AKA 'things that people would actually be interested in', rather than something like "hey we're 50% to our goal" or "we've added these stretch goals", etc.

I don't have anything to compare it to, but as of right now our video numbers are:
45,000-ish on the kickstarter page and... actually about the same on youtube too, 45,000. For the youtube numbers, a HUGE factor in that was being posted on major sites like RPS, Kotaku, Joystiq and The Verge. I remember being pretty stressed after a big update went out and for two days the youtube plays for it was at like <200. Then RPS posted and in a matter of hours it was at 4,000.

I don't know how much of this will be helpful, but please feel free to ask away, I'm be happy to help!





   JLJac on February 23, 2014, 01:15:09 PM:

Hi everyone!
Has anyone else had this problem:
If I need to put to Unity's debug logger every frame, it runs smoothly for about a second or two, then it freezes for 0.5-1 second, then it runs a second or two again, etc.
I'm supposed to be able to put a value to the console once per frame, right? It makes it really hard to do stuff, because putting to the console is the only way I know of to keep track of a value.

Is it just my computer that's slow? Weird that the frame rate isn't consistently low then...?





   JLJac on February 23, 2014, 01:42:03 PM:

Yeah? That's not right?
However I found out that just putting the number on the screen with a Futile "label" (text thingie) doesn't cause the same problem, so now I've got something that works Smiley





   JLJac on February 24, 2014, 06:07:34 AM:

Ok, changed it to fixedUpdate! What's the difference, even?

Other, more important question - how do I delete an instance?

And remove it from the list it's in, of course. The best solution would obviously be to have some kind of destroyMe function to call, where the object would find itself in the update list and remove it self. Problem is, we're currently looping through the update list, so there's a risk it'll skip an item.





   JLJac on February 24, 2014, 06:25:46 AM:

Thanks a bunch Smiley
I prefer to have objects own instances of sprites rather than inherit sprite behavior (that way one object can have many sprites), so I have some sprites to delete as well for each object. But I guess that can be done simply enough by running a custom destroy function in the object, where the sprites are killed and a destroy bool is set to true, and then run your solution. Thank you thank you!

Is this true for every instance ever? I never have to actually kill an object, because if I just kill the reference to it it will be taken care of?





   JLJac on February 24, 2014, 06:48:42 AM:

Wonderful! Seems too good to be true!
The sprites actually stay on screen - inactive - if I remove the object. The way it works in futile, from how I understand it, is that you create an "atlas" which is a big texture, and then all the sprites can draw their little part of that texture, minimizing draw calls.

My guess here is that the futile framework keeps track of its sprites itself, and that's why they still hang around on the screen. I'll just have to find some kind of keyword for Futile sprite removal, but Futile's entire documentation is this one reddit page haha XD And I'm the worst at reddit, I don't even know how to make a localized search happen. Good times!





   JLJac on February 24, 2014, 09:11:45 AM (Last Edit: February 24, 2014, 09:32:35 AM):

Hm, wow... Is that an issue to the degree where it might be worth it to in some cases (thinking particle system) save instances of objects in some kind of vacancy list and bring them in later, rather than deleting/respawning them?

Gentlemen, here's a programming question for you:

If I have to sort an unknown amount of some object by some property, how is that done?
Say that I have a projectile travelling through the air. I've made a line from the object's last position to its current position, and checked that line towards the objects in my game. It shows that the line intersects objects A, B and C.

What I want to do now, is to sort the objects by their distance to the projectile's last position. The object that's closest to where the projectile was last frame was hit first, and it's to this position I want to move the projectile, and it's this object I want to be affected by it.

In lingo, I'd do it like this:

Code:
distanceList = []

distanceList.add( [distance(projectile.lastPos, A.pos), object reference to A] )
distanceList.add( [distance(projectile.lastPos, B.pos), object reference to B] )
distanceList.add( [distance(projectile.lastPos, C.pos), object reference to C] )

distanceList.sort()

myHitObject = distanceList[1][2]
hitObjectDist = distanceList[1][1]

Basically a 2D array, and when asked to sort it would sort by the first position in the sub-array.

In C# though, I have to define what data type the slots in an array is, and making a 2D array seems much more bothersome. Does anyone have any good tips on how to do this? I'd be super happy for some kind of general solution, where you can sort anything by anything. Like, "which player out of these 4 have the most points" etc.

Thank you Grin

Edit: Oh yeah, maybe I should be clearer - I know there is an "orderBy" keyword, which I will definitely look in to, but in this case I want to keep the property I'm sorting by. When doing orderBy it seems the property you order by dissapears after the sorting is done, and also it seems you have to calculate it again, you can't throw in a value you already have. This means that in the above case, if I use OrderBy, I'll have to calculate distance no less than three times - first when repeating through the objects and checking if I want to add the object to the list, then again when sorting, and then a third time when I actually retrieve the closest object and start doing stuff to it. In my Lingo solution, I could calculate it just once, throw it in the list, sort the list by it, and then grab it again after sorting.

Edit edit: I could create a custom class, that has only an object reference and a value to sort by, and fill the list with those. But that seems garbage collection heavy, right?





   jamesprimate on February 25, 2014, 01:53:10 AM:


ah thats awesome!!! i wish they would have used a higher res video though, geez that was like 480p youtube nonsense at best Tongue





   JLJac on February 25, 2014, 10:21:08 PM:

@Rabbit, I'm glad someone except me is also getting something out of this!

@dancing dead, that's the method I ended up using! My problem was that I didn't understand that I could declare a variable without assigning it an instance ("closestObject"), but then I learnt about "null" :D And now I see that in your example, you don't assign the variable at all! Wow, I'm learning soooo much!

@Juan, thank you! Alright, fixedUpdate it is. Note though that I use a "buffer" or "time stacker" or whatever you'd call it in order to make my frames happen at consistent intervals (similar to the last method described here http://gameprogrammingpatterns.com/game-loop.html) so the difference might not be that significant - it's not like the game runs faster if there are fewer objects on the screen. But I will check out what it's like if I split the updates into one game object update cycle and one that's only for graphics - I like to move the sprites towards an extraploation of the object's position in order to get a super smooth look on computers that can handle that.

Random questions of the day:

You guys mentioned that I could make Unity display stuff without anti aliasing, "pixel" style. If I have an image imported into Unity I think I know where to change this, but Futile runs its own thing with atlases, and I wonder if anyone knows how to change that setting in there?

Casting, guys. Right now I have a variable called "objectType" for the like for all objects, and whenever I want to grab an object out of a list and do some type-specific stuff to it, I just switch case on objectType and then I cast that mofo as whatever class I know it to be. This basically circumvents the limitation that you have to specify the class of things as you pass them around. I've started to learn though, that the annoying limitations are there for my own good (for example I've finally actually understood why globals are bad). So my question is - what's the catch? Why shouldn't I just cast everything according to an "objectType" variable?

Global functions can't be any harm if they don't access anything outside the parameters they're fed, right? If I want to make a custom function for something very general like converting degrees to a normalized vector or something, that's not a problem, right?

If I want to set the position of an object, I can do either this:
pos.x = 400f;
pos.y = 200f;
Or this:
pos = new Vector2(400f, 200f);
How come that for the latter one, I have to wastefully create a new instance? What happens to the old instance of "Vector2", it's left for garbage collection, right? Is there any alternative that keeps the line count down while at the same time doesn't waste memory and time by creating a new instance and replacing an old one?





   JLJac on February 26, 2014, 06:23:39 AM:

@dancing dead, that's actually exactly how I do it! The problem has been when I want to do something like collision. I use inheritance in my little "learning c#" thingie, and I have some objects inherit from a "physicalObject" cast. (I'm very interested in this "interfaces" thing you mention though, will check that out!) When two objects collide, both of them gets a collision function called, where the object they collide with is passed as a PhysicalObject. Problem was, if they for example was a bullet I wanted to do bullet-specific stuff with them on collision, and that's where my casting mess came into play. Now I'm dying to implement "is" and "as" instead though! At this pace, my brain won't fit in my scull tomorrow evening!

@Juan, cool! I'll try to find the atlas from inside the code... Maybe there is some kind of unity command to return the current assets in the project or somthing like that, and I can use that to find it. GetType won't really do anything I can't use the "is" keyword for right now, except it might work better for switch cases? Important question, what's the data type of the return on the GetType function? Is it a string called "PlayerClass" or is it some kind of separate data type that's made to hold the ID's of classes?

@Sebioff, that seems really cool - thanks a bunch! For now I think globals will be enough, but when I want to make things even leaner I'll remember the extension methods :D

@8-Bit Ape, thank you very much!





   JLJac on February 26, 2014, 06:44:24 AM:

Hehe Juan I just need to be clear about this, don't feel obliged to help me every time I ask for it, you'll end up doing nothing else Tongue I'm suuuuper thankful though :D

If I wanna do a switch case on class type for an instance, do you recommend converting it to string first? Or maybe to... enum?

On the tutorial, I did that one, and those specific settings aren't in there. Isn't there any text file with just all the functions of futile stuff anywhere? Like, if you can write "Futile.atlasManager.LoadAtlas" what else can you put after "Futile.atlasManager. ..."? If I just had a list of those commands I could experiment and try to figure things out, but now I feel like I'm a bit too much in the dark Sad

Edit: Like, here https://github.com/robert-wallis/GameJamKit/blob/master/Assets/UI/UISetup.cs it suddenly shows that you can call something called "GetFontWithName" on AtlasManager... So there are obviously more things you can do with it. There has to be a full list of all those commands somewhere, right?





   JLJac on February 26, 2014, 07:38:58 AM:

Actually it does! And there are some functions there - and it didn't help me very much Sad Nothing like "atlasAsTexture" or anything like what I had been hoping for ... I guess I'll have to try reddit.





   JLJac on February 26, 2014, 07:49:24 AM:

The thing I want to set seems to be "filterMode" - the Unity documentation puts it like this:

renderer.material.mainTexture.filterMode = FilterMode.Trilinear;

This doesn't work for Futile though, because the Futile game object doesn't have a renderer, it says. But it has to have one, right? Or a material? I'll keep experimenting...





   JLJac on February 26, 2014, 08:12:58 AM:

Thank you!!!

The problem is that I don't have any by-unity-recognized textures to apply filterMode on. I did search in the Futile atlasmanager file, and in LoadAtlas (which is what I'm using) he clearly defines a 2d texture:

Quote
   public FAtlas LoadAtlas(string atlasPath)
   {
      if(DoesContainAtlas(atlasPath)) return GetAtlasWithName(atlasPath); //we already have it, don't load it again
      
      string filePath = atlasPath+Futile.resourceSuffix+"_png";
      
      TextAsset imageBytes = Resources.Load (filePath, typeof(TextAsset)) as TextAsset;
      
      if(imageBytes != null) //do we have png bytes?
      {
         Texture2D texture = new Texture2D(0,0,TextureFormat.ARGB32,false);

         texture.LoadImage(imageBytes.bytes);
         
         Resources.UnloadAsset(imageBytes);

         //texture.filterMode = FilterMode.Point;
         
         return LoadAtlasFromTexture(atlasPath,atlasPath+Futile.resourceSuffix, texture);
      }
      else //load it as a normal Unity image asset
      {
         return ActuallyLoadAtlasOrImage(atlasPath, atlasPath+Futile.resourceSuffix, atlasPath+Futile.resourceSuffix);
      }
   }

That "  //texture.filterMode = FilterMode.Point;" is my attempt to change the filter mode, but it did nothing Sad

I tried moving it around, still, nothing. The problem is that I don't understand the code here, so I don't know what I'm doing. I suspect that this texture is just some throw away variable used for loading, and the one used when the actual application runs is somewhere else. Searching the Futile script files for the word "texture" hasn't done much good though...

Gah, programming is hard! I'll check if there is some kind of Unity command that just returns a list of the currently loaded textures, that would be a decent hack if I can't find where the texture is actually created.





   JLJac on February 26, 2014, 08:29:41 AM:

Hehe this is super embarrassing, but I actually found the solution:

After reading this:
http://www.reddit.com/r/futile/comments/y2q5p/futile_tips/
I tried navigating to the atlas .png file in the Unity editor, select it and change the filter mode there. It worked.
 -_______________________-

I was so focused on finding a way to do it with code that I didn't try the simplest possible way - just doing it through Unity's interface.

Thank you all for having patience with me.





   JLJac on March 01, 2014, 09:50:37 AM:

dancing dead, I'll try your approach and let you know if it worked!

Juan, thanks! Sorry!

Weird C# problems that I can't understand:

I wanted to do a thing where one thing was affected by another thing more the closer it was to it. I tried to solve it like this:

Code:
float frc = (150f - Vector2.Distance(obj1pos, obj2pos))/150f;
frc = Mathf.Clamp(frc, 0f, 1f);

Easy enough, no? frc decreases linearly with distance, at distance > 150 frc is zero. But no! For some reason this returned small values slightly above zero, never a clean zero. Even if the distance is greater than 150 (which would mean that the value I try to Clamp becomes negative, and therefor should be set to 0.0, in my opinion). I even tried removing the Clamp and doing an old school if statement, with the same weird output. If I tell it to log just the first line in my example, I get a reasonable number such as -72.423. But after trying to restrict it, it's never a clean zero. What's going on here!?

Other problem: I wanted to generate a color at random, but I only wanted fully saturated colors and never white or black. My solution was to have one of the rgb values be full, one empty, and one a random from 0.0 to 1.0. My attempt at a solution was something like this:

Code:
colorsL = new List<float>();
colorsL.Add(0f);
colorsL.Add(1f);
colorsL.Add(Random.value);

playerColor = new Color(0f, 0f, 0f);

int getPos = Random.Range(0,2);
playerColor.r = colorsL[getPos];
colorsL.removeAt(getPos);

getPos = Random.Range(0,1);
playerColor.g = colorsL[getPos];
colorsL.removeAt(getPos);

playerColor.b = colorsL[0];

So basically I create a list which holds three values, Zero, One and Random. Then I pick one of these at random, assign it to the red parameter, delete it. Pick one of the remaining two, assign it to the green parameter, delete it. The one that's left goes into the blue parameter.

For some reason this would never give the entire spectrum of colors, blue was always full if I remember correctly. I changed it for a switch case on a random number, and wrote 6 cases manually, but that seems like a super hacky solution. What was I doing wrong?

Edit: Bonus question! In the original tutorial I did, all the parameters in classes where declared as public. I continued doing this by default. Is this practice good/bad? I noticed that you can simply not write "public" and it will still run just fine. From my understanding "public" makes the variable changeable from outside the class, and it seems more self-contained and object oriented to keep that to a minimum, perhaps?





   JLJac on March 01, 2014, 10:18:57 AM:

Hehe sorry, clumsy of me! Now it works just fine Smiley
When looking at the code, does the solution look conventional or like the alien makings of a self-taught weirdo? I worry about this a bit, because I don't want to drift into weird territory if I'm to bring another programmer on later on...





   JLJac on March 01, 2014, 02:02:09 PM:

Thank you very much for the help and the reassurance :D

Embarrassingly I'm unable to repeat the bug... Sorry Sad Probably it was just a screw up on my side...

Here's a more interesting issue:

Futile has something called "containers", basically the same as movieClips in flash - they're sprites that can have other sprites in them, and they can be nested in each other. I'll be using those for layering my graphics, and also I might use the nesting because that would make it possible to do cool stuff like fade out the entire HUD with just one line of code.

When adding sprites, I need to reference what container to add it to. So I use a "global" array that's a property of the main game instance in order to keep track of them. An object can say, for example, "add this sprite to container 3". It looks like this in my code:
Code:
tpGame.SpriteLayers[2].AddChild(spr); 

Here's the fun part: Ideally, I don't want a linear array of layers, but a tree-like array, reflecting the nested containers.
Code:
                      |Game Graphics -----  ForeGround        |Explosions
Main Container -------                     |                  |
                      |HUD  ---| HUD1      | Game Layer ------ Players
                               | HUD2      |
                                           | Background --- Bkg Image
                                                           |Bkg Sprites

It seems like a solution like this would make more sense than having a document by the side where you have a note that says "item 6 in the list is the Background sprites layer" - that's not very elegant.

In the best scenario possible, I'd want to be able to write something like:
Code:
tpGame.SpriteLayers.GameGraphics.Background.BkgSprites.AddChild(spr);
And I know that this can be accomplished by defining a class for each and every intersection in the tree, but if elegance is what I'm after, that doesn't seem like the way to go XD

Is there any way to create a tree-like structure like this? Note that all the branches can be different lengths.





   JLJac on March 02, 2014, 01:34:22 AM (Last Edit: March 02, 2014, 01:53:01 AM):

Thanks guys! Wow, dictionaries and hashtables seem awesome, though I still haven't been able to figure out the exact difference between them...

Juan, your solution seems pretty amazing! It would enable me to name, remember and access every sprite, right? I'm not sure I understand it 100% hehe ... I just worry about the memory it would take to store names for hundreds of sprites D:

So, for my problem, maybe the simplest and most "elegant" solution would be to add all my containers to an old school array, and then use a dictionary to store their indexes? That way I could access something like this:
Code:
tpGame.SpriteLayers[sprLrsIndxDict["Background"]].AddChild(someSprite);

The question that comes to mind in that case is why not to use an enum? Then the auto complete would help me remember what I named all my layers.
Code:
tpGame.SpriteLayers[(int)SpriteLayerIndexer.Background].AddChild(someSprite);

Or, even better, maybe you could create an enum where the data type is a futile container?
Code:
FContainer  bkg = new FContainer ();
FContainer  fg = new FContainer ();
enum SpriteLayers : FContainer {Background = bkg, Foreground = fg};
SpriteLayers.Background.AddChild(someSprite);

That would be totally awesome, because it would be a neat way to clump together related data, and name it according to its function and have the autocomplete help me remember the names!

Then I could use that for a loooot of things! For example, if I want to store the some parameters for the playable level area, I could go like:

Code:
enum LevelParams : float {LeftPadding = 10f, RightPadding = 10f, RoundCornernsRad = 5f};
And then just access that easy as pie, without having to create a cumbersome class that would only be created in one single instance either way. I'm gonna try this out right now! The only thing that could make me happier would be the same thing but able to store mixed data types, and I think I read something like that in the Dictionary documentation page... To the hackmobile!


Edit: It turns out the enum structure is very particular about what data types it takes Sad Only int, byte, long and a few others are valid. Perhaps a dictionary is the best way to create a list where you access stuff by a name rather than by an index number, then?