Author Topic: Shrugger! Unity!  (Read 151217 times)

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #330 on: September 25, 2015, 06:37:50 pm »
Neato! Thanks  :D

I don't get the column headers à la "Average - Worst - Worst" though. What's the deal here? Are those average/worst-case scenarios?
The beatings shall continue
until morale improves!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #331 on: September 25, 2015, 11:16:35 pm »
Neato! Thanks  :D

I don't get the column headers à la "Average - Worst - Worst" though. What's the deal here? Are those average/worst-case scenarios?

Yes. It should be noted that "best case" under spring is essentially "sorting a sorted array" which tells you nothing. Average and space complexity are the important factots. Less space means less GC. Better average case, less CPU (you'll now that there are trade offs there: faster often means more memory).

n is a stand in for the size of the list, k is a constant of some indeterminant value, and 1 is 1. I forget what m is.
For big-o notation, exact values are irrelevant: O(2n) isn't much different than O(n) or O(100+n). The first one is slower, but it isn't more complex. The last has some overhead, but has the same complexity.
That is: O(1) takes the same amount of time, regardless of the size of the list. O(n) takes the same amount of time as there are elements (think a loop that oates over each element once: each item takes the same amount of time, but the longer the list, the more time the whole loop takes). This is why the "best case" of sorting is always O(n), that's how long it takes to verify that the list is sorted.
And so on up the complexity tree.

What isn't there is the big-o for insertion into the middle of an array list (or at least, I didn't recognize it). Which I think is O(n) CPU and O(1) memory.

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #332 on: September 26, 2015, 03:46:28 am »
Aaah, yes, O-Notation. I'll probably write yet another exam about it in a few months. Algorithms and Data Structures...I slept through that lecture a year ago, but by now I know better  ::)

Time Complexity, I'll guess, is just a fancy term for how long it takes?
The beatings shall continue
until morale improves!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #333 on: September 26, 2015, 12:20:23 pm »
Time Complexity, I'll guess, is just a fancy term for how long it takes?

Yes, in the general sense.  It's a relationship between "how many items" and "how long it will take" but makes no guarantees that a lower complexity algorithm will perform better under any given circumstance, just that as the number of items grows, the higher complexity one's time will grow more quickly.

Have a neat little video that will give you an idea of how things work in practice.  There's a couple of them.
https://www.youtube.com/watch?v=es2T6KY45cA

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #334 on: February 16, 2016, 03:09:39 pm »
We're currently trying to implement Chemistry, and it's a bit tricky on the programming side.

So far we've gone with one abstract class Substance from which a variety of substances like Hydrogen : Substance, Graphite : Substance and Water : Substance inherit. These substances have a number of static properties like Density, Conductivity, Composition and potential Reactions.

But we've problems with the specifics of how to use those classes. Approaches tried so far:

  • Individual instances for every use - stupid, especially for GC.
  • Singleton pattern - cannot call instance from base class.
  • Static classes - cannot inherit, and cannot be referenced.
  • Interface instead of base class - cannot have default implementations of various methods.

Does anyone have a good idea of what's best done in such a situation?
The beatings shall continue
until morale improves!

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: Shrugger! Unity!
« Reply #335 on: February 16, 2016, 03:15:40 pm »
Have an enum SubstanceType and a class SubstanceTypeData which has one of those enums, and then whatever fields (which are set in the constructor based on a switch on the enum, and the constructor is called for each enum by a static SubstanceTypeData.Initialize() call) ?

That's what we do for most of our "lookup table" data, though lately we've done some where the records are defined by xml rather than by enum/ctor-logic.
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Shrugging Khan

  • Hero Member Mark III
  • *****
  • Posts: 1,217
  • Neinzul Y PzKpfw Tiger!
Re: Shrugger! Unity!
« Reply #336 on: February 16, 2016, 03:27:37 pm »
Thanks!

So it'd look like:
Code: [Select]
public enum SubstanceType { Hydrogen, Helium, ... }
public class SubstanceTypeData {
 private SubstanceType substanceType;
 public SubstanceTypeData (SubstanceType substanceType) {
  this.substanceType = substanceType;
 }
}
How would I reference a Substance elsewhere, though?
Keep one instance each in a static table class and refer to that?
The beatings shall continue
until morale improves!

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: Shrugger! Unity!
« Reply #337 on: February 16, 2016, 03:31:39 pm »
Here's an example, from the Starward Rogue codebase:

Code: [Select]
public enum InventoryItemType
{
    None,
    Energy,
    Keycard,
    Missile,
    Credit,
    HealthShard,
    ExperiencePoint,
    Length
}

public static class InventoryItemTypeExtensionMethods
{
    public static InventoryItemTypeData GetData( this InventoryItemType Type )
    {
        return InventoryItemTypeData.Lookup[(int)Type];
    }
}

public class ArcenEnumIndexedArray_InventoryItemType<T>
{
    #region Instance Fields
    private readonly T[] internalArray = null;
    #endregion

    #region ctor
    public ArcenEnumIndexedArray_InventoryItemType()
    {
        this.internalArray = new T[(int)InventoryItemType.Length];
    }
    #endregion

    public T this[InventoryItemType key]
    {
        get
        {
            return this.internalArray[(int)key];
        }
        set
        {
            this.internalArray[(int)key] = value;
        }
    }
}

public class InventoryItemTypeData
{
    public readonly InventoryItemType Type;

    public string Name = string.Empty;
    public IGameImage CannotPickUpBecauseFullIcon;
    public IGameImage RecentTransactionListIcon;

    public int Max = -1;
    public int Default;
    public bool UsesSimpleHUDDisplay;
    public bool ShouldTrackPositiveChangesInTransactionLog;
    public bool ShouldTrackNegativeChangesInTransactionLog;

    public InventoryItemTypeData( InventoryItemType Type )
    {
        this.Type = Type;

        string cannotPickUpBecauseFullIconName= string.Empty;
        string recentTransactionListIconName = string.Empty;
        string recentTransactionListAnimatorName = string.Empty;
        int animDictWidth = 0;
        int animSpriteWidth = 0;
        int animFrames = 0;
        switch ( this.Type )
        {
            case InventoryItemType.None:
            case InventoryItemType.Length:
                return;
            case InventoryItemType.Energy:
                this.Max = 100;
                this.Default = 100;
                this.UsesSimpleHUDDisplay = true;
                break;
            case InventoryItemType.Keycard:
                cannotPickUpBecauseFullIconName = "FullIconKeyCard";
                recentTransactionListIconName = "Items/PickupKeycard";
                this.UsesSimpleHUDDisplay = true;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.Missile:
                this.Max = 10;
                this.Default = 5;
                cannotPickUpBecauseFullIconName = "FullIconMissiles";
                recentTransactionListIconName = "Items/PickupMissile1";
                this.UsesSimpleHUDDisplay = true;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                break;
            case InventoryItemType.Credit:
                this.Max = 255;
                cannotPickUpBecauseFullIconName = "FullIconCredit";
                recentTransactionListAnimatorName = "Items/PickupCredits1";
                this.UsesSimpleHUDDisplay = true;
                animDictWidth = 160;
                animSpriteWidth = 32;
                animFrames = 19;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.HealthShard:
                this.Max = 10000;
                animDictWidth = 370;
                animSpriteWidth = 74;
                animFrames = 18;
                recentTransactionListAnimatorName = "Items/PickupHealthShard";
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            case InventoryItemType.ExperiencePoint:
                recentTransactionListAnimatorName = "Items/PickupExperiencePoint";
                animDictWidth = 96;
                animSpriteWidth = 24;
                animFrames = 12;
                this.ShouldTrackPositiveChangesInTransactionLog = true;
                this.ShouldTrackNegativeChangesInTransactionLog = true;
                break;
            default:
                throw new Exception( "InventoryItemTypeData.ctor: no switch case defined for InventoryItemType '" + this.Type.ToString() + "'!" );
        }

        if ( cannotPickUpBecauseFullIconName.Length > 0 )
            this.CannotPickUpBecauseFullIcon = Game.Instance.LoadImage( "Misc/GameUnitPopups/" + cannotPickUpBecauseFullIconName, 58, CompressionType.None, TextureWrapMode.Clamp, false );
        if ( recentTransactionListIconName.Length > 0 )
            this.RecentTransactionListIcon = Game.Instance.LoadImage( recentTransactionListIconName, 52, CompressionType.None, TextureWrapMode.Clamp, false );
        else if ( recentTransactionListAnimatorName.Length > 0 )
        {
            OtherAnimator animator = OtherAnimator.Create( recentTransactionListAnimatorName, animFrames, CompressionType.None, TextureWrapMode.Clamp, animSpriteWidth, animDictWidth, 1, true );
            this.RecentTransactionListIcon = animator.Images[0];
        }
    }

    public static InventoryItemTypeData[] Lookup = new InventoryItemTypeData[(int)InventoryItemType.Length];
    private static bool HasInitialized = false;

    public static void Initialize()
    {
        if ( HasInitialized )
            return;
        HasInitialized = true;

        for ( InventoryItemType i = InventoryItemType.None; i < InventoryItemType.Length; i++ )
        {
            InventoryItemTypeData typeData = Lookup[(int)i] = new InventoryItemTypeData( i );
        }

        LoadLoca();
    }

    public static void LoadLoca()
    {
        for ( InventoryItemType i = InventoryItemType.None + 1; i < InventoryItemType.Length; i++ )
            i.GetData().InstanceLoadLoca();
    }

    private void InstanceLoadLoca()
    {
        this.Name = Language.Current.GetValue( "InventoryItemType_Name_" + this.Type );
    }
}

Initialize is called during application startup logic, and individual references are serialized/deserialized as Int32 casts of the enum itself, and if you have a reference and want the data you do item.GetData().whatever .
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #338 on: February 17, 2016, 12:13:30 am »
Here's an example, from the Starward Rogue Arcen Engine codebase:

FTFY :P

TLF has codeblocks like that too for various things.

Offline keith.lamothe

  • Arcen Games Staff
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 19,505
Re: Shrugger! Unity!
« Reply #339 on: February 17, 2016, 03:18:02 am »
It is a common pattern, yes. And more than one game has had an InventoryItemType, though generally it gets ripped out at the beginning of each new project (along with most stuff) and then added back in when actually called for :)
Have ideas or bug reports for one of our games? Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline Draco18s

  • Resident Velociraptor
  • Core Member Mark V
  • *****
  • Posts: 4,251
Re: Shrugger! Unity!
« Reply #340 on: February 17, 2016, 04:21:53 am »
Mhm ;)

Offline Mad Rubicant

  • Full Member
  • ***
  • Posts: 103
Re: Shrugger! Unity!
« Reply #341 on: February 17, 2016, 05:29:00 pm »
XNA hijack!

So I'm working on my own project, using Monogame, and I'm not really sure how to load all my sprites in a non-blocking way. So say I have 8 million images to load, obviously I can't do
Code: [Select]
foreach sprite in sprites {
Content.Load(sprite)
}
since that will block for however long it takes to load the images. How can I get around this? As far as I know my options are async or threading, and I have no idea how to use either.

Offline Hearteater

  • Core Member
  • *****
  • Posts: 2,334
Re: Shrugger! Unity!
« Reply #342 on: February 17, 2016, 06:26:49 pm »
Check out Content Tracker. Even if you don't use it directly, the code should help you get the right idea.

Offline Mad Rubicant

  • Full Member
  • ***
  • Posts: 103
Re: Shrugger! Unity!
« Reply #343 on: February 22, 2016, 04:42:12 am »
Well, I managed to throw something together that seems to work. We'll see whether have threading I errors in a few months.

Offline Mad Rubicant

  • Full Member
  • ***
  • Posts: 103
Re: Shrugger! Unity!
« Reply #344 on: June 20, 2016, 04:47:46 pm »
So I have a question about Entity Component Systems. I decided that it wasn't worth the trouble rolling my own physics engine, and am in the process of integrating Farseer Physics, but now I've got a weird duplication problem. Before I started using it, I had a PositionableComponent that was combined with a DrawableComponent to be used by the rendering system, but with Farseer handling distances for me, it's a little redundant. But requiring a PhysicsComponent for anything that can be drawn is overkill. Should I keep the PositionableComponent and redundancy, or just fold that stuff into the DrawableComponent? This is all 2d, of course.

Also, the forums are being weird as hell; my reply box isn't wrapping the text and instead extending all the way to the right