Jump to content
  • Advertisement

Whistling Alpaca Studios

Member
  • Content Count

    12
  • Joined

  • Last visited

Community Reputation

5 Neutral

About Whistling Alpaca Studios

  • Rank
    Member

Personal Information

  • Interests
    Art
    Design
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Whistling Alpaca Studios

    Unnamed Itemshop

    Album for Unnamed Itemshop
  2. When we started working on this project we had the mindset of "Random is good enough". Most of our systems were running off of pure randomness, which for our very small data set was perfectly fine. If you had a list of craftable items to pick from, and you had 3 or 4 items, just doing at Random.Range() over the list would be perfectly acceptable. I noticed this would become a big issue when we introduced randomized quest requirements. Of course, randomizing over the full set of items made the requirements total nonsense. Even when we narrowed down the blacksmith, he could be asking you to bring him 1 copper ore, or 1 Epic Adamantine Mace, he didn't care. One of the easiest and most useful solutions for the problem were: loot tables (and other tables which I'll get to later). In the future I'm sure I'll increase the following logic to allow for more than 100 percentage points. public class LootTable { List<LootTableItem> items = new List<LootTableItem>(); public LootTable(List<LootTableItem> _i) { BuildListFromPartials(_i); } public void BuildListFromPartials(List<LootTableItem> _i) { int previous = 0; foreach(LootTableItem item in _i) { item.LowEnd = previous; item.HighEnd = previous + item.PercentChance; previous += item.PercentChance; } items = _i; } public Item RollForItem() { int roll = Random.Range(0, 101); foreach (LootTableItem item in items) { if(roll == 0 && item.LowEnd == 0) { return item.GetAnItem(); } if(item.LowEnd < roll && roll <= item.HighEnd) { return item.GetAnItem(); } } return null; } } And the supporting class: public class LootTableItem { //The chance that this item will be rolled (out of 100). public int PercentChance; public int LowEnd; public int HighEnd; public List<Item> PossibleItems; public LootTableItem(string item, int percentChance, int quality = 0) { PercentChance = percentChance; PossibleItems = new List<Item>(); PossibleItems.Add(ItemManager.GetItem(item, quality)); } public Item GetAnItem() { return PossibleItems[Random.Range(0, PossibleItems.Count)]; } } The declaration of a loot table can look a little gnarly, but it's pretty easy to understand. Before long I was creating loot tables for everything, including items you'd get from harvesting: new LootTable(new List<LootTableItem>(){ new LootTableItem("Copper Ore", 60), new LootTableItem("Iron Ore", 40)}); You can call lootTable.RollForItem() as many times as you want, which is why you can easily augment this strategy by adding rolls. I also stripped down the loot table to simply support weighted chance, allowing me to give the player multiple rolls on harvesting, so the better their equipment the better their chance of getting good items. The difference in this example is that instead of just saying "if the user has an +2 axe equiped, give them Random.Range(0,2) extra rolls", you can weight the outcomes. So you wouldn't have a 1/3 chance to get a 0, 1 or 2. You could have a 50% to get 0, a 30% chance to get 1 and a 20% chance to get 2. With this concept you can easily tweak your item collection outcomes to allow your players to have a significantly more fair experience. You can even tweak the rates if you keep getting really bad results.
  3. Whistling Alpaca Studios

    'Play From Zero' Development Philosophy

    Basically continuous deliverables: https://en.wikipedia.org/wiki/Agile_software_development
  4. Whistling Alpaca Studios

    'Play From Zero' Development Philosophy

    This is an excellent approach to all software development in general. Getting something in a working state as early as possible is really great for getting creative. I always hated having documentation before hand on what exactly corporate enterprise software was going to be, so when we jumped on the Agile Bandwagon it was actually awesome. Not only could you get software done faster, but you figured out that clients rarely wanted the specifics of what they asked for. This translates so well into Game Development because you game grows very organically. Just make sure you're using some kind of Kanban board if you're with a team otherwise all those ideas will get lost. Also: Meet early, meet often
  5. Whistling Alpaca Studios

    Unnamed Itemshop

    Your humble item shop sits as one of the only markets of free trade in the world. The Guilds control the flow of goods. Prices are fixed by them and deals are struck. Your family's shop has been granted sole rights to serve as an intermediary Item Shop, it now falls to you to continue the tradition of exploiting the constant back and forth between the various guilds.
  6. This is a very straight forward method to achieve this effect. The area behind the rock is walk-able and will hide the player in the render order and the front will show the player on-top. I've been very happy with the way the tilemaps are working in unity, once you get used to it they really make sense. Getting your character to appear in front of and behind objects is done with splitting the sprite in half and putting them on different layers. The important part is adjusting your box collider on your player so they never clip through these objects, this is what we're using for ours: Our player sprite is 16x32 and I typically split all of my tilemaps into 16x16. The sprite renderer on the player is important too, the "player" sorting layer is in front of the default layer. Our bottom layer just needs to be on the default layer and have a collider; just stamp that bottom layer in there. Our top layer just needs to be a higher value than our player. If you're using tilemaps and you're going for this top-down RPG aesthetic I think you'll get a lot of mileage out of this method to really bring out depth.
  7. At this point in development you could say that we have a few managers running the various elements of the game: Anything that requires singleton behavior gets a manager. From the guilds to the player's stores to the zones an inventory icons we're leaning heavily on these managers to get the job done. Anything that doesn't need to be a singleton and can exist as a static class just gets to set there being static. To expand on why you may need managers which are singletons, the way we handle inventory icons is a good example. We have a ton of icons, such as these: that we need to feed into the game and map off to an item type (they are default icons for item types). With our singleton manager we can simply pass these sliced icons as parameters in our prefab's inspector: And now there's a reference to our items mapped to their type and everything is nice and clean. Except...How do you access the ItemIconManager prefab? Are you going to type GameObject.find(...)? Absolutely not, that's where the Manager's Manager comes in! Manager's Manager physically hurt my heart to write, so I ended up naming it the "Manager Loader". Now your ManagerLoader can maintain a reference to all of your prefab managers. And load them individually. The only person in the hierarchy here that needs to be marked DontDestroyOnLoad is the ManagerLoader itself, so you don't repeat yourself in all those child managers. My Manager Loader has 2 things that are important here. A list of references to the Prefabs of the Managers, and a static List of the instantiated prefabs: Then all I do is instantiate the managers and load them into my static list like so: private void LoadAllManagers() { if(Managers != null && Managers.Count > 0) { InstManagers = new List<GameObject>(); foreach (GameObject go in Managers) { GameObject instanceGo = Instantiate(go); InstManagers.Add(instanceGo); instanceGo.name = go.name; instanceGo.transform.SetParent(transform.root); } } } At this point we have static references to all our Managers inside of our Manager Manager...Er, Manager Loader, and if we want to reference them its as easy as: public static GameObject GetManagerByName(string name) { foreach(GameObject gameObject in InstManagers) { if (gameObject.name.ToLower().Equals(name.ToLower())) { return gameObject; } } return null; } Now instead of searching through every game object we only have to go through as many managers as you have. As long as you're comfortable sacrificing space for speed, you're set up for success here. I guess you could even store the managers in a dictionary for even faster reference! Now there's an idea. Keep chuckling, Mr Blacksmith...Keep chuckling.
  8. Whistling Alpaca Studios

    Unity Tilemap White Line Issue

    Antonsem, This solution didn't end up working for me. The Anti-Aliasing solution you see all over the web when you search for this issue reduced the occurrence by quite a bit, then the pixel snap reduced it some more (to almost nothing). Then I swapped over to the LWRP material pipeline and never really got the pixel-perfect camera working (yet). Our current workflow has simplified this down REALLY well though, since it's an RPG top-down style game we're able to just create a single tilesheet that has all our ground tiles, then we add a 2px boarder to all sides of the ground tiles. Since we have significantly fewer ground tiles than anything else, this process is very low effort. Sidenote: The LWRP 2D lights are really fun/easy to work with.
  9. Whistling Alpaca Studios

    Unity Tilemap White Line Issue

    One of the issues we ran into is this fairly well documented Unity Tilemap white line issue. When you have a tilemap in unity, with really a large repeating area you''ll usually end up with a pretty glaring issue coming from the tilemap. You'll notice long, weirdly colored lines appearing vertically (as I've seen it) on your tilemap. According to what I've been able to tell this comes from your camera not snapping to a whole number pixel count, which seems to be the issue in my case. My camera follows the character in a pretty slow way, approaching the character quickly than slowing down the closer it gets. There's basically two solutions that I've found to fix this issue and they're both pretty straight forward. The first fix is the fastest, and usually works, you simply find your container grid for your tilemap and give the cell gap a bit of a negative offset, in this case -.01: This is the fastest way to solve this problem, but I've noticed that it doesn't always work. If the above solution isn't working you're going to need to get dirty and add a 1px padding to all of your tilesets that show this problem. Since it would be a massive effort to redo all of your tilesets, I'd recommend finding the offending tile and testing if something like this works. Take the tile that's causing the issue, and surround it with copies of itself like so: Simply apply that center tile to the whole map you're trying to test and you'll be able to tell if this is the issue and dedicate more of your time to getting each one of your offending tiles that 1px buffer. In my case, there needed to be BOTH of these solutions in order for the tilemap to look correct. Overall this is going to be one of those problems that you poke and prod at until you find something that works for you, just make sure you run around your map and make that camera move in weird directions to see if you can get your issue to reproduce!
  10. Whistling Alpaca Studios

    Managing UI between scenes in Unity

    Coming up with a solution for managing UI elements across different scenes wasn't as trivial as I first expected. It's very easy to attach a canvas to a scene and call it a day. Initially, I had all of my canvases attached to the first scene I expected the player to enter and then simply call DontDestroy(gameObject) on all of the canvas scripts. So what's the issue? If you allow the user to save and load from other areas, you have to copy/paste a prefab into each of your other scene. This is a trivially easy solution, but it's too dirty for my liking, instead, we should dynamically create and manage the UI elements via a UI manager. The first step would be to create an empty object in our loading screen (the loading screen will always be accessed before gameplay starts). In this case, since we're also going to be appending a bunch of canvases to this empty object, it needs a canvas or stuff just doesn't render properly. Also, make sure to add a reference to your UI element prefabs: And the start script for the UIManager script: void Start() { if (allCanvases == null) { DontDestroyOnLoad(gameObject); foreach (GameObject prefab in prefabsToInst) { GameObject toAdd = Instantiate(prefab); toAdd.name = prefab.name; toAdd.transform.SetParent(transform); uiCanvases.Add(toAdd); } } else { Destroy(gameObject); } } Each canvas appends itself to the UIManager and therefore does not get destroyed on scene change. All specific behavior for each individual canvas can be handled in the individual UI component's scripts. Blamo! That's it! Crisis averted, we can now navigate between scenes and know that our UI manager is now empowered to show canvases, hide them, etc. Note: This article was originally published as a blog entry here on GameDev.net by Whistling Alpaca Games.
  11. Unnamed Item Shop first month In this devlog we'll be discussing the various aspects of what we did in our first month of development. We'll cover important things like what we accomplished and how we set our expectations and processes to get the most out of the time we had. One of the first things we did to give ourselves a very vague direction was to make a few statement about what the game was. We first came up with the very baseline statement: "You run a fantasy item shop". As long as the game meets those expectations, we were on the right track. Instead of trying to rigidly force the game to be something, we are creating the systems one by one to enhance our first main idea. Things We Accomplished: Art: One of our big challenges was coming up with an art style we liked while also keeping a resolution and feel that would be easy enough to do within our time limit. We were initially thinking about doing a 32 pixel base size, but ended up going with a 16 base pixel size because we were able to get plenty of detail and style. Not to mention the characters came out looking absolutely cute. We're doing very well on the amount of sprite sheets we have already created with enough assets to make the entire player's shop, most of the exterior scenes and a few of the other interior scenes in the game. Since the pixel art represents basically every aspect of the game, this section can be summarized as: Everything you can see, is the art we've accomplished. Systems: We started creating systems for the game by layering various managers over each other as well as other independent systems such as character movement, pause functions and camera movement. Keeping these systems completely separate proved to be incredibly useful earlier this week. We were faced with a major refactor of the inventory system, it was the first thing I started working on with the game and since it's my first unity project it had several issues. A refactor was in order and because the systems were so independent, after I ripped out the entire inventory system all other systems were functioning fine. The shop system was also working pretty well, customers will walk around the player's store visiting a random amount of points of interest before deciding if anything in the shop is worth them buying. The user is also able to set custom prices on each item in their store, which works really well both in the fantasy of the game and as a mechanic (Also note the placeholder icons 👍) . All of our UI components are also broken out into prefabs, which makes it incredibly easy for our UI manager to perform all CRUD operations on them. Guilds, a fairly major feature in the game, are also implemented (although I only have 2 coded at this point). Each one can consume or produce resources and each interact with each other based on those resource production/consumption. It's currently in the air if we're going to do guild reputation at this point. Summary Overall I think we were able to get a lot accomplished, especially considering the fact that this is our first month of development time. We had a lot less direction and far fewer goals in the beginning, but now that we're under way we really are just blasting along. I think one of the most important things for us was to set an impossible development time, while keeping the focus of the game razor thin. If we get to the end of that development time and there's something missing or the requirement to add more systems we can easily add additional development or testing time. Also since we're beholden only to us and what we want to get out of this game we're not burdened with meeting other people's expectations. The first month has been very eye opening. Learning new software, learning a process that works for us (as a two person team) has all been really cool and we're looking forward to the next month of development.
  12. Coming up with a solution for managing UI elements across different scenes wasn't as trivial as I first expected. It's very easy to attach a canvas to a scene and call it a day. Initially I had all of my canvases attached to the first scene I expected the player to enter and then simply call DontDestroy(gameObject) on all of the canvas scripts. So what's the issue? If you allow the user to save and load from other areas, you have to copy/paste a prefab into each of your other scene. This is a trivially easy solution, but it's too dirty for my liking, instead we should dynamically create and manage the UI elements via a UI manager. The first step would be to create an empty object in our loading screen (the loading screen will always be accessed before gameplay starts). In this case, since we're also going to be appending a bunch of canvases to this empty object, it needs a canvas or stuff just doesn't render properly. Also make sure to add a reference to your UI element prefabs: And the start script for the UiManager script: void Start() { if (allCanvases == null) { DontDestroyOnLoad(gameObject); foreach (GameObject prefab in prefabsToInst) { GameObject toAdd = Instantiate(prefab); toAdd.name = prefab.name; toAdd.transform.SetParent(transform); uiCanvases.Add(toAdd); } } else { Destroy(gameObject); } } Each canvas appends itself to the UIManager and therefore does not get destroyed on scene change. All specific behavior for each individual canvas can be handled in the individual UI component's scripts. Blamo! That's it! Crisis averted, we can now navigate between scenes and know that our UI manager is now empowered to show canvases, hide them, etc.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!