Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics


A member registered Mar 10, 2014 · View creator page →

Creator of

Recent community posts

That is great I was worried you might get stuck on this one (as anyone easily can)

(4 edits)

Please don't go overly complicated with game saving. Start small, release, expand/fix later. Don't try to save complex stuff from the start (let game lose some data); saving/loading just structures, resources and where/how many units there are - will be more than enough for now! Even just structures will be ok for first release.
I say that because serialization can easily become very complicated, especially when you  want to save graphs (ai planning states) or object references (guaranteed duplicates when deserialized naively) - headache^2, don't even go there right now!

(1 edit)

(0.12.11) Idea: Ability to sell any resources to docked ships

Not only fuel. If for nothing else - just to free container space

(0.12.11) Idea: Option to recruit more staff from passing or docked ships for $

(0.12.11) Idea: Containers that accept only specific resource type

Visual clue would be nice too (different container color or decal of resource icon)

(0.12.11) Bug: Pausing game produce strange, looped noises

It's just annoying that those noises wont ever go away :T even when game is running in background (after alt+tab or minimized)

(0.12.11) Dillema: No amount of containers is enough

There is no way right now to cap, for example, how much of minerals or ice mining lasers prospect. This always results in more container being needed all the time.
I think that a list of max global resources would be better than manual "Ignore Resource" drag&drop panel.  In this scenario given resources would be just be placed in ignored state every time when specific quantity is met

Game is much better and stable now! :) I see no units being zombiefied for no apparent reason anymore. Truss and module building system was a good choice too

(1 edit)

(0.12.9) Bug Feature: Priorities

How to kill all your crew in 3 easy steps:

  1. Expand your station, make sure everyone is busy with important tasks.
  2. <meanwhile> Toilet becomes fully filled with... content. </meanwhile>
  3. Thats it, game over. Everyone dies of diarrhea because f****** nobody wants to clean it up anymore and prefers just to wait in line until their a** explodes :O

(5 edits)

(0.12.7) Bug: WorkManager.RevalidateJobs throws  900ms-long tantrums for reasons

Repro steps:

  1. Create a floor tile completely enclosed with walls somewhere
  2. Create a build order for container on this tile
  3. Connect that isolated tile (with build order waiting) to the rest of the base
  4. Watch as one worker comes to construct it and fails at it doing it forever
  5. Cancel that build order to fix it
  6. <CPU fan cooler accelarates to mach 1>

(5 edits)

That's great!

PS: Please don't over-rely on events (outside UI ofc). Those are 10x times slower and complicate future debugging considerably. If something can be just a method call - let it be just that, you will thank yourself for that later on (less time spent debugging==more productivity==happier you).

(4 edits)

Unit tests are of some value Only when you find yourself actually testing something manually a lot and would love to automate that - in other situations it's mostly another costly vanity coding.

Exception #1: Big enterprise software, where codebase maintenance and stability is more important than change (creative work does that a lot)

Exception #2: Well staffed MATURE game projects going for stable release

(5 edits)

I have no idea what service locator pattern is and I'm glad for it! :T
In my personal experience implementing patterns is very luring but only to become a very costly vanity work (and sometimes even deadly one to given project). Because in later stages of development everything becomes so horrendously complicated that everyone is praying for simplicity, productivity stalls.
Keep it simple - this is most undervalued yet most productive pattern out there (!).

I'll check that next time but it very well may be it!

(7 edits)

Easy (but lazy) solution to most of those allocations would be to use LazyCacheStrings and change your code into something like this:

public static LazyCacheStrings<ItemType> ItemTypeStrings = new LazyCacheStrings<ItemType>( (t)=>t.ToString() );
static LazyCacheStrings<System.ValueTuple<float,float>> TitleStrings = new LazyCacheStrings<System.ValueTuple<float,float>>( (kv)=>string.Format("Items {0:0} / {1:0}",kv.Item1,kv.Item2) );
static LazyCacheStrings<System.ValueTuple<ItemType,float>> SectionStrings = new LazyCacheStrings<System.ValueTuple<ItemType,float>>( (kv)=>string.Format("{0} {1:##}",ItemTypeStrings[kv.Item1],kv.Item2) );
void Update ()
    ItemContainer container = SingletonMB<StationContent>.Instance.GetContainer();
    title.text = TitleStrings[ ( container.CapacityUsed , container.Capacity ) ];
    int numContainerItems = container.Items.Count;
    for( int i=0 ; i<numContainerItems ; i++ )
        ItemStack itemStack = container.Items[i];
            ItemTypeStrings[ itemStack.Type ] ,
            SectionStrings[ ( itemStack.Type , itemStack.Amount ) ]

This should limit worst of this runaway allocations just some seconds after game start (once caches fill up). It's not the best solution but certainly the simplest one to implement.

(3 edits)

To give you an example of how to get rid of string allocations think about creating lookup tables for your values (enum is easy and natural candidate for that). This is how you create an lookup table for enums:

public static readonly Dictionary<ItemType,string> ItemTypeStrings = new Dictionary<ItemType,string>{
            { ItemType.Metal, "Metal" } ,
            { ItemType.Food, "Food" } ,
            { ItemType.Water, "Water" } ,
            { ItemType.Mineral, "Mineral" } ,
            { ItemType.Dirt, "Dirt" } ,
            { ItemType.WasteWater, "Waste Water" } ,
            { ItemType.LOX, "LOX" } ,
            { ItemType.LH2, "LH2" } ,
            { ItemType.AsteroidaldWater, "Asteroidald Water" } ,
            { ItemType.MetalOre, "Metal Ore" } ,
            { ItemType.Component , "Component" } ,
            { ItemType.None , "None" } ,

And that will give you an ability to replace every:

string myTypeString = itemStack.Type.ToString();//allocation


string myTypeString = ItemTypeStrings[ itemStack.Type ];

which will allocate no memory at all (==what we want)

(5 edits)

After cleaning code up just a bit it can be like this (cleaner to read/understand imho):

void Update ()
    ItemContainer container = SingletonMB<StationContent>.Instance.GetContainer();
    title.text = string.Format( "Items {0:0} / {1:0}" , container.CapacityUsed , container.Capacity );
    int numContainerItems = container.Items.Count;
    for( int i=0 ; i<numContainerItems ; i++ )
        ItemStack itemStack = container.Items[i];
        string identifier = itemStack.Type.ToString();
        string text = string.Format( "{0} {1:##}" , identifier , itemStack.Amount );
        sectionLines.Set( identifier , text );

Note that 'string.Format()' is slightly better than '"strA"+"strB"'

Also System.Text.StringBuilder would be better (string.Format uses it internally).

(5 edits)

Few words of friendly comments:

void Update ()
    // *** - ToString allocates at least 2 bytes for every character
    // **** - adding strings together with '+' operator is more or less equivalet to ***
    ItemContainer container = SingletonMB<StationContent>.Instance.GetContainer();
    TextMeshProUGUI title = this.title;// this does nothing - remove line
    float num = container.CapacityUsed;
    string str1 = num.ToString("0");// ***
    num = container.Capacity;// reusing local variables is not needed for anything
    string str2 = num.ToString("0");// ***
    string str3 = "Items " + str1 + " / " + str2;// ****
    title.text = str3;
    foreach( ItemStack itemStack in container.Items )// unfortunately, starting 'foreach' allocates memory - in Update methods try to use simpler old 'for' iterator instead of 'foreach'
        PanelSectionLines sectionLines = this.sectionLines;// this does nothing - remove line
        ItemType type = itemStack.Type;
        string _identifier = type.ToString();// ***
        type = itemStack.Type;// this does nothing - remove line
        string _text = type.ToString() + " " + itemStack.Amount.ToString("##");// ****
        sectionLines.Set(_identifier, _text);

Downsides of ToString() calls are not that simple to get rid of in context of UI. But it's better that you're aware of it and step-by-step will be trying to avoid them in the future (strings in general).

(7 edits)

(0.12.6) Bug: GeneralItemPanel.Update method is allocating >10MB of garbage memory PER SECOND.

This leads to GC.Collect() calls causing this pattern of CPU spikes:

This 180KB seems like nothing... until you actually multiply it by your framerate.
One probably won't even notice this bump on high-end machine but it can seriously throttle any weaker laptop or older pc. And for no valid reason really.

PS: I have no idea from where this Instantiate call is coming from but it looks like that is the biggest offender here allocation-wise (consider object pooling).

(3 edits)

( Bug: Launching game via app launches an installer instead of actual game executable.

(7 edits)

(0.12.6) Bug: Build menu UI becomes stuck and unresponsive.

Repro steps:

  1. Build a mining laser
  2. Demolish it before constructed
  3. Click on different build cathegory icons until this thing happens
(4 edits)

(0.12.6) Bug: Devices sometimes just aren't being constructed.

Workers do other things and seemingly ignore it.

(6 edits)

Friendly tip: try not to rely on singletons. Those seems fancy at first but are more trouble than they're worth in the end. Just pre-instancing them manually in the editor and accessing them through fields isn't that hard and will make your program more resilient. Meaning just:

[SerializeField] BuildManager _buildManager;



instead of:

(3 edits)

Oh I see... bc these are cheats codes :)

.FindEmptiest(Game.Station.Device.DeviceType.Storage, ItemType.Metal).Container.Add(ItemType.Metal, 100f);
(2 edits)

(0.12.6) Another NullReferenceException in main menu

(that burst of asteroids I guess)

NullReferenceException: Object reference not set to an instance of an object
  at Game.Objects.Asteroid.AsteroidFactory.Awake () [0x00008] in C:\Users\Taz\Space Architect\Assets\Scripts\Objects\Asteroid\AsteroidFactory.cs:13 
UnityEngine.GameObject:AddComponent(Type) (at C:\buildslave\unity\build\Runtime\Export\Scripting\GameObject.bindings.cs:222)
UnityEngine.GameObject:AddComponent() (at C:\buildslave\unity\build\Runtime\Export\Scripting\GameObject.bindings.cs:227)
SingletonMB`1:get_Instance() (at C:\Users\Taz\Space Architect\Assets\Scripts\Utils\SingletonMB.cs:34)
AsteroidManager:GenerateBurstLine(Int32) (at C:\Users\Taz\Space Architect\Assets\Scripts\Managers\AsteroidManager.cs:77)
Game.InputManager:Update() (at C:\Users\Taz\Space Architect\Assets\Scripts\Managers\InputManager.cs:40)
(Filename: C:/Users/Taz/Space Architect/Assets/Scripts/Objects/Asteroid/AsteroidFactory.cs Line: 13)
(2 edits)

(0.12.6) Pressign keyboard keys in main menu causes NullReferenceException

NullReferenceException: Object reference not set to an instance of an object
  at Game.InputManager.Update () [0x0004e] in C:\Users\Taz\Space Architect\Assets\Scripts\Managers\InputManager.cs:43
(1 edit)

Where do I send bug reports?
0.12.5 callstack:

(Filename: C:/Users/Taz/Space Architect/Assets/Scripts/UI/Panels/VisitorPanel.cs Line: 60)
NotImplementedException: The method or operation is not implemented.
  at Game.UI.Panel.VisitorPanel.HandleLeft (Game.Visitors.Visitor _visitor, System.EventArgs e) [0x00001] in C:\Users\Taz\Space Architect\Assets\Scripts\UI\Panels\VisitorPanel.cs:60 
  at (wrapper delegate-invoke) <Module>.invoke_void_Visitor_EventArgs(Game.Visitors.Visitor,System.EventArgs)
  at Game.Visitors.Visitor.CallLeft () [0x00001] in C:\Users\Taz\Space Architect\Assets\Scripts\Visitors\Visitor.cs:136 
  at Game.Visitors.Visitor.Remove () [0x00001] in C:\Users\Taz\Space Architect\Assets\Scripts\Visitors\Visitor.cs:115 
  at Game.Visitors.Visitor.Update () [0x00114] in C:\Users\Taz\Space Architect\Assets\Scripts\Visitors\Visitor.cs:81 

This game is far more harder than Flappy Birds! :)

Awesome! That was like Mirror's Edge but with vastly more vicious ducks.

This is like brain-gym

Cool adaptation, i like it.

This is closest thing to poetry I've seen here. 5*

Enjoy protection of local police officers! I fixed them :D It looks like sleep deprivation somehow fogs my fundamental sense of logic.. :T

Thank you for your feedback! Much appreciated and I'm looking forward to hearing more from you.
So I just added an arrow in radar view to help player find what he needs.
I will try to repair policeman ai too so he would behave accordingly again (this feature broke just about hour before #cyberpunkjam's deadline ;_;).

Look, Rate button :3