Support Me on Patreon

Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Monday, May 11, 2020

And everything changes again.

I LIVE!

A week after the Covid-19 lockdown my laptop's HDD died, and swapping it out was a pain. A few other problems arose and my three-year-old HP laptop dies completely. I was able to cobble together a desktop without internet access (no service where I live). My cousin's phone gets crap reception in my room (but it gets reception); a dongle and tether later I'm able to access the IRS webpage.

Let me spell it out.

Due to my heart condition\s, and the Covid-19 crisis, I'm unable to have gainful employment. I'm also not disabled enough for any kind of help (major vital organ, really?).
My heart is good, just has some electrical problem due to a previous surgery from birth, and other developing problems (my left arm is a bit numb).

I have a lot of aggression. I'd consider it "anger issues" if I didn't have control (I'm being reminded that laziness isn't control). Sterilize-the-planet levels of wrath. This aggression is great for my focus, not so great for my health or control. After the loss of my laptop (and most of my data) I'm livid.

The government stimulated me, so I have a new laptop. I'll spare the details, it's last year's model so I could keep some money. I've meds to buy and plans to lay.

Now where was I?

Little One may have had some files corrupted, I need to re-assemble the project from backups (Always keep multiple backups). I've got some ideas for Adventures' EDGE (I didn't plan well enough for that) and ideas for future projects.

For now I'm just going to try putting all my focus into my projects, and hoping it doesn't hurt me too much. My focus and aggression can cause chest pains, but I'm not sure the precise trigger. Time for some pomodoro rushes.

Pomodoro rush:
The use of several pomodoro intervals (four or more), each focusing on a different task (two or more) in rotation. Breaks optional, but suggested.

So now, my plans:

Little One need to be brought back up and finished, need to ease into that.
Adventures' EDGE might be going 2D. It'll probably get a turn-based battle system as well.
Resources (2D & 3D) might be created and uploaded to OGA.





Thursday, January 30, 2020

Naughty Plot

This post will cover ideas and tips for the more mature game types, however I'll be avoiding vulgar or descriptive bits. Not like I'll ever make one and most of these tips can be used for virtual pet games.

Rub-a-dub:

Touching, poking, or petting is relatively straightforward. Either an invisible collider or area is attached to a bone and may have metadata attached. This attachment is usually set to detect mouse or touch inputs. Using signals connected to a script can turn that input into variable values to change a character's mood. This is usually the easiest mechanic to make, but the longest to perfect.


Designer "pet":

Character creation systems are nothing new, but how they are handled relies on numerous factors. Doing them in 3D is easiest, but layering sprites or using 2D animation skeletons allow customization in 2D games as well.

You'll first want one or more protoform characters without hair, skin color, or defining features. Their looks can be altered easily with textures and extra items (accessories). Shape keys (vetex animations) can be used to define other body features (nose, hands, etc.). Using clothing textures can be faster than 3D clothing, but can have a few restrictions. 3D clothing can allow inside objects to clip outside. With just a few characters, textured clothing offers few benefits, and combining both can be useful. If there are more than ten animated characters, clothing textures can help with lag if you have it.

This mechanic has many parts to it, don't become discouraged if things don't always work as intended.

Pose this way:

Custom poses can be done in most game engines. There are several ways to do it, even if the engine doesn't allow direct access to the skeleton, blending animations can be useful. Godot allows skeletal access and bone manipulation via script and allows animation blending. Creating a pose can be done by making a dictionary, using the bone names as keys, and adding the bone vectors to it.

Poses are nice for a screenshot, but what if you want the player to make their own animations? Godot allows full access to the animation data via scripting, and should be able to create and save an animation. Of course, building and saving the animation(s) would involve even more work, so providing plenty of animations yourself is a good idea.

If an engine does not allow access to animation data, consider hacking your own in with dictionaries or json files. The mark of a good developer is how obstacles are handled, not avoided.


Make the camera dizzy:

Camera controls can range from great to abysmal, which is why I like first-person cameras. For any "pet" game, it is best to center the rotation nodes on the character themselves. Have two spatial nodes for 3D rotation (and rotating them on individual axes) gives the easiest control. Remember to add a camera reset button to reset the camera position and node rotations (in case the player messes up the camera).

Camera zoom can be done either through movement, or changing the FOV. Checking the camera's distance from a specific point (one of the axis or gimbal nodes) allows you to set limits to how far the camera can go.

This is relatively easy to implement.

Mods mods mods:

Creating or adding mods to the game is usually *technically* possible. Since any engine *should* be able to read their own data formats even after compiling. I'm not entirely sure how to go about it in godot, but there is a way to load, modify, and save almost anything within run. The main problem is making sure resource scenes have everything they need and are organized. While I'm not sure how Godot feels about zip files, a json file in a mod folder could help.

Here are a few ideas:

Putting the mod and associated files in a folder with a json file. The json file would tell the game about the mod, resources needed, and type of mod (character, object, prop, scene).

Having a zip file, with a json file. It's really the above tip, but zipped.

Using  self-contained scene file and putting these files in the appropriate mod folder.

Using a scene compiled to a pck file by the engine, however I'm not sure how this could work. This could make mods easier to load.


###   ###   ###

Warning: inhibitor 34 unstable


Tuesday, January 7, 2020

Mechanically Disinclined

You've got a fantastic game idea, don't you? Listed all the things you want to be in it and put in a little planning, right? Maybe you've planned the maps and resources needed as well? Now you are just sitting there, wondering where to start. Enemies, crafting, inventory, which mechanic should you start upon?

The place to start in any major project is the foundation. In games, that would be the core mechanic. There are several types of mechanics in games, core, supporting, challenge, and extra/other. I'll go over these mechanics so you can better identify them and choose the actual core mechanic.

Core mechanics, although there is usually just one, are used throughout the game; or to beat the game. Minecraft is obviously crafting, since you have to craft tools, weapons, and armor to progress. Mario games have Mario's base moveset (jump, punch, kick) as the core mechanic. Fighting games have character movesets as the core mechanic. Can you guess Pokemon's core mechanic? It's not capturing, but battling. You have to battle to progress or win the game, like any base RPG, but capturing is needed to get more characters to battle with. Capturing is a support mechanic.

Support mechanics are used to support the core gameplay. Minecraft has mining. You have to mine wood to get materials to craft tools for more mining. Mario usually has support pickups (mushroom, fire flower, tanuki) while most fighting games just use the core mechanic. With Pokemon, capturing is the support mechanic to get characters to battle with (no capture nuzlocke anyone). Most challeng mechanics are used to control the games pacing or make it more fun. If you could just beat Bowser without collecting the macguffins and unlocking the worlds, Mario games would be boring.

Challenge mechanics are used to give the player a challenge. For most games, this is usually the enemies you fight. Sometimes the challenge mechanic is a support mechanic as well, like in Pokemon. Minecraft would be even more boring without the mobs to kill, but it would still be nice to explore. Timers, puzzles, goals, and achievements are usually challenge mechanics. Anything that is used to determine/cause a losing scenario is usually a challenge mechanic. Player stats are a great example of a simple challenge mechanic.

Now for the final type of mechanic. Extra/other mechanic usually don't affect gameplay much, but it can add to it. For Pokemon, the trading mechanic is extra. All the Pokemon could be in a single game, but trading was added to expand the game. Similarly, items in Super Smash Bros. and Mario Kart are extra (but fun) mechanics. Wile these extra mechanics add to the game, too many can bog down the game or expand development times (going to ludicrous dev time). If it isn't a core or support mechanic, work can usually be delayed upon it.

Some things to consider about mechanics. Some games are just a core mechanic (fighting games). The advertised mechanics are not always the core mechanic (pokemon). Some games can have either two core mechanics, or core/support symbiosis (minecraft) where the core and support mechanics work together to hold up the game. Core mechanics can also support other mechanics. Extra and challenge mechanics should be the last worked on and the first to be cut. Online play is almost always an extra mechanic. Inventories are almost always a support mechanic.

You should almost always work on the core or support mechanic first. As a developer, you can give yourself the macguffins needed to use the core mechanic. Unless the core mechanic really needs a support mechanic, start with the core mechanic. Mechanic don't have to be perfect, just working; polish can come later.

Little One just had two main mechanics when I started, the vacucell collector and farming. Item collection was the core mechanic and farming was actually supposed to support a challenge mechanic. Those were the first two mechanics I started with.

Blue Bloom has several mechanics, more than Little One. I was confused at first what mechanic to start upon, but crafting will be the core mechanic. Resource collection will be a support mechanic with the flora and fauna being challenge mechanics. In fact, Blue Bloom will have several challenge mechanics.







Tuesday, December 31, 2019

Fragmented Post

I'll be posting on a few different subjects in this post, so scroll to the bolded area that interests you.


Game Optimizing Tip: Conga Loading

Adding and removing objects from a game can cause a bit of lag. This is evident when dealing with numerous objects that need to be loaded/unloaded. This is why I usually just move existing objects around, like raindrops or particle effects. The bigger problem comes from objects that have to be swapped out, like NPCs or monsters. You don't want enemies milling about hundreds of units away from the player, and capping the spawn rate makes this worse. Still, removing all those unrendered  monsters and adding fresh could cause a dip in frame rate. Why not deal with them singularly?

The idea is to connect signals between the monster and a router node. The router node can be anything, but it needs a script to handle signals and connecting them. Signal connection via script is a bit tricky, so I won't go over it here, but it is a great skill to learn.

When the monster/NPC need to be unloaded, or a node needs to load an entity, it first polls the router with a signal containing itself and a request for the action. The router then adds this node to a list of either incoming, or outgoing. While running, the router swaps between out or in (boolean value) every tenth or twentieth of a second. If there are nodes queried,  then a signal is sent allowing the node to either add something, or remove itself. This allows for a single-in single-out entity loading system, reducing load.

To do something every second, or second-fragment, use a delta timer. This is just a variable that has the delta, or frame time, added to it. Once it reaches a specific amount or greater, an if statement allows some code to be run and the timer variable is reset to 0.

Who Duolingo: Tips for Duolingo

I use the Duolingo app to learn Spanish. While it won't make you a pro, it will give you the skills to converse a bit in another language. Here are several tips and things I've noticed.

Start with small daily goals until you get used to the app. Daily goals can be changed in the app settings, usually a gear or those three dots. I started small and worked my way up to the highest amount.

Double mint lingots.With a few exceptions, you get lingots when you meet daily goals or complete a level. You can sometimes watch an ad to double those lingots. When on wi-fi, go ahead and double the lingots. On data I don't watch the ad unless I am doubling two or more lingots. Lingots are useful for doing tests, getting a few extras, and getting more lingots. If you have plus, lingots lose some of their value. I think you can also give lingots to others by upvoting their comments on a lesson (the speech bubble when you complete a lesson).

Gotta do my stories. Sometime around the second section, I unlocked the stories.These are short stories that are easy and short. They tend to give over twenty XP for each one and usually take a few minutes. Since you can re-do the stories, this is the bet way to get plenty of XP. However, reaching the daily goal this way will NOT earn any lingots. Using it to get close, then doing a lesson or practice for the remainder, will give you lingots. XP boost does not work with stories.

Double XP may not be free. Occasionally, the shop will allow you to get double the XP from your lessons, but it is a bit complicated. Reaching your daily goal under this juice won't net you any lingots. reaching another level will get you lingots. Using the XP boost doesn't work on stories. I'd avoid using the XP boost until you have reached the daily goal, to maximize points and lingots.

Testing 1-2 testing 1-2. When you start a lesson, or course, there is a light-bulb and a key. The light-bulb opens a primer on the lesson, giving you tips. The key allows you to take a test and level-up the course. For just five lingots (or zero with plus) you can level up your skills. This is useful if you are good at a course and are getting bored, but sometimes it is better to do the entire course instead. A successful test nets twenty points, failure nets a disappointed Duo. If you fail, either finish the course normally, or try again later (like a day or more).

The hard easy is an easy hard. You may notice that some lessons are harder than others. Tests are no exception, so it is better to take a test after a hard lesson. This gives a greater chance that the test will be a bit easier. There is no guarantee, but it can help.

Slow and steady wins the test. Slowing the dialog on lessons that have dialog may be annoying, but don't take chances during a test. You may think you have the listening skills down cold, but some vocalists are better than others and I've let my pride fail me a few times. Personally, I'd take every hint that Duo gives, especially when I'm a little unsure. Since tests don't have many hints, I'd slow the dialog for a slight edge.

You know nothing, and the birb knows it. Each section has several courses. At the end of a section, there is a test. In my foolishness, I assumed I knew some Spanish. From ZERO to TEN I chose one and was promptly put in my place for my pride. Starting at zero, especially for the first section test, is advisable.

Report it. Duolingo isn't perfect. Sometimes it gives you wrong hints or an answer you give should be accepted. At the end of a lesson, you can ether see user's comments (text baloon) or report a problem (flag). If there is a problem, flag it and explain it. Together we can make Duolingo better. Try to be respectful, unlike me; I tend to have a temper.

Green and red. Correct answers get a green popup while wrong answers get a red popup. Those popups can obscure your answer, hindering learning. Touch a blank area of the popup to slide it down. Now you can check how wrong you were and learn from it.

Play for me, Little One

I had a plan to finish Little One by the end of 2019. That didn't pan out like I had hoped. Most of the items left to add are minor and I could add two or three per day. Since there is another project I wish to get started upon, I'll probably default to adding an item to Little One each day and focus on my next project. For now I'm just trying to make sure Little One is in a beatable form before the next update. The ending will be sparse, and I'll add both it and the opening later, but it should be completable.

My plan is to rest for New Years (eve, day, and day after). I'll try to upload a build on the last day of 2019, but I have to pick up some medicine that day and this post won't be tweeted until that day or after. On the days I'm resting, I'll flesh out the plans for my next project. The ending scenarios are planned, so I'll work back from those. Mostly, I'll be listing the mechanics and writing pseudo-code for them.

The openings and endings of my project may be done with vector art. It seems easier to make several panel images and flip through them like a book. Text will probably accommodate the images. Since I'm doing this alone, and some days are better than others, I'll take the route of least resistance.

Aside from the story images, there are a few things to add before Little One is feature-complete. The critters need animations and additional coding. Beasts need to be planned, modeled, ect. Several parts will need models and textures before being added. Part droppers need to be coded and added. Player damage, sleeping, and recovery needs to be coded. Several props and a couple dialog elements are still missing. I'm going to try getting the vacucell to suck up other liquids, and the critters will bring several items to the game. Many of the building upgrades are unfinished as well, and need models, textures, and programming.


Better as of late than never.


 Yesterday (12-29-19) I felt like I was moving through molasses. I managed to get the material droppers done and in the game. These drop a few materials daily to assist with building and part creation. After a nap I felt much better, but I usually relax after I take my meds at six.

I've added quite a few things to Little One. Mostly the parts and upgrades crafting. The upgrades seemed to work well without any extra coding in other areas. Sometimes I'll go to add something just to learn it's either there already, or I've done the preliminary work; making a feature easier to add. Keeping future and related features in mind as you program will help you add the needed functions and code to support future additions. Planning can help immensely as well, and I should have planned Little One a bit more.















Friday, December 13, 2019

Player: ReLoaded

Finally got the player model imported with animations. At first, I just added the animation setup to the player scene, but I knew I'd need to refactor the player. Starting with a copy of the animation setup, I copied the script and test room then started working. Referencing the original player, I added all the accessories and gave them the groups and signals needed. Since so much had changed, minor edits were required for the script's copy.

Initial tests went well. Objects fired at near-lethal velocities, so I had to scale back their speed. Vacucel aiming was a bit off, so I adapted it. Items were collected slightly better and faster. All the buildings and menus thus far work.

The major problem came from the water pools. Water was being spawned, but it kept falling into the pool before collection. Most times it wouldn't seem to appear. After some debugging (print statements) the problem was located. For some reason, the water was spawning too low. I just added an extra unit to the spawn's Y axis for a quick fix.

I'm not looking forward to adding the dialog system, but that may come next.

Tutorial, How to Debug Code:

Most times when there is a syntax error, you either get a warning or a crash. Most script editors take you somewhere close to the offending line so you can find the problem. With godot, the error is usually above the line indicated. Most flaws are within a few lines of the line indicated, if not the line itself. Remember, these editors are making a best guess, so they can be a little off.

However, sometimes something doesn't work for any number of reasons. Sometimes you cannot see the error because it's logical (and that skill may need a few levels). If a specific mechanic isn't working in a game, your first option is to check the area of code for that mechanic. Usually, this is contained in a function for ease of use. Often, just looking will reveal the problem.

If not, I like to add print() statements in the code and output different strings or values. hen the statement at the top of a function doesn't print, then the function isn't being called. More code to check, but you could have forgotten to call the function. This is also useful to check if statements in a similar way. When the requirements of an if statement are not met, it won't activate.

Printing variables can help determine if they have the correct values, or that they are being used. An errant or empty value can cause much mayhem. Bad incoming variables are also problematic, so check them if you have them.

If all else fails, get a rubber duck and read the code's lines to it. Then kick yourself smartly when the solution is obvious. The solution is almost always obvious.







Friday, December 6, 2019

The Panic Mechanic

I'll just go over some game mechanics and the basics of how I'd do them. These are just ramblings, there is no guarantee they'll work in any engine and I'm not providing technical details or code.

Delta Timer.

Just a variable that starts at 0.0. You can add the delta or any number to it each frame during any process that runs each frame (or at specific times). Once it gets to an amount you want, do something and set it back to 0.0. They have a majority of uses and you can have as many as you need.

First Person Shooter:

I like FPS and first-person cameras. They're easy to do since the camera is the player. You don't need any complex camera mechanics to keep the camera with the player. Godot's engine docs have nice tutorials for this. Mostly you just rotate the player L/R with mouse movement and the camera U/D with mouse movement. The other movement keys (WADS/Arrows) are mostly for strafing. The only problem is making sure the strafing is affected by rotation.

The guns come in two main types, hitscan and projectile. Hitscan is mostly for bullet and energy weapons while projectile is for grenade/s and rocket launchers.

Hitscan:

I know it's a projectile weapon, but if the projectile moves at sonic speeds you'll want this. It mainly uses a raycast or other pointer/area/collider. When you "fire" you check if the raycast is colliding and check if what it's colliding with is in a specific group or has a specific variable/property. Groups are great for this. Now just reduce that target's health. Adding a muzzle flash helps.

If you hit a wall, get the hit position and add a hit decal. These are mostly 3D planes with sprites on them. To avoid Z-fighting, you could have the decal raised a bit from the object center. Getting the rotation right is a bit tricky, either use the face normal or invert the player's Y rotation.

Protip: Keep several hit decals in the scene and grab them all in a list. Move one where the wall was hit. Use a variable to keep track of which decal you are using and loop through them. No adding/removing of objects needed.

Muzzle flashes are ether 2D or 3D objects that appear for a second. You can use timers, but here's a better idea. Spin the flash and make it visible when the player fires and invisible when the player releases. The flash can also turn invisible based on a delta timer that increments while the player is pressing the fire button.

Projectile:

These weapons "throw" an object. Rigid bodies are great for most of these. You just have to add the object to the end of the weapon and give it some speed. Just be careful it isn't too close to the player or they blow you up, BOOM!

Most of these projectiles have an area that detects "hits". You'll have to use an explosion animation or particle setup and cause damage to the hit object. I'd have several of these setups in the map, move them to the collision, and use an area attached to them to determine what gets hurt. This can play a single animation or particle effect, sound, cause damage, and then go inert and be moved away. This is similar to the pro tip with hit decals.You'll also have to remove the projectile.

Tip: An object playing a sound cannot play the sound when it's removed. Timers can help, but other object setups are useful too.

For sticky grenades, try making them a child of the thing they hit.


Sit, Stand, Lean, and Crouch:

Crawling on the floor looks fun, but doing it in a game is easier than you think. First, you'll need different collider setups or collision shapes for each position. A state machine will help, but I've never done one of those yet. When the player/NPC changes positions, just enable the appropriate collider and disable the other colliders. You'll have to use different animations when prone, but this is a simple way to do it.

Sitting is just making the character either a child of the seat, or positioning them appropriately. Disabling the character's or the seat's collider helps.


Inventory:

There are many different kinds of inventories. The most basic one is a list or array. I personally use dictionaries that either contain arrays or other dictionaries. You really only need the item name and amount in any slot. More complex item data can be held in another dictionary. Selecting, picking up, and using items are all more complicated.

I'd use Godot's ItemList nodes, then iterate through the inventory and add the items. The docs can cover more than I. For picking up, you'll have to iterate through the inventory to check if you have that item. If the slot isn't at the limit, add the item's amount. Otherwise, start a new slot. Those if statements tend to get rather long and loopy.

Time:

Also know as a clock or a day/night cycle. Mostly it's just a delta timer that increases the "minutes" once it gets to 1.0. Once the "minutes" reach a specific amount, increase the "hours" and make the minutes equal zero. You can figure out the rest.

For showing the clock I use a label on the HUD and use a custom font. Godot's normal font is small. You'll want to format the text output a bit, but that's easy.

The day/night cycle requires either animating the sky or animating a material on a sphere. It is very complex and I'll only give one tip.

Tip: If you need to use a sphere/dome for the sky, make it change its position to the player if it's smaller than the map.


That's pretty much all I'm going to post today. There might be more later.











Thursday, November 21, 2019

Saving Games

Godot Engine already has a tutorial about saving games here, but it may not be for everyone. Basically, it grabs all the nodes in the “Persist” group and writes them to a file. It does this line-by-line, but you might just want to dump a dictionary to a file and grab it again.

I'm assuming you are using a singleton (preload) scrip that holds the game data. Singletons are scripts that load before any others and can hold persistent data for the game. Dictionaries are a complex datatype that can keep things organized. Since dictionaries are passed by reference, they are easy to keep updated.

func save_world():
    var saveFile = File.new()
    saveFile.open("user://savegame.save", File.WRITE)
    saveDat["Cells"] = cells
    saveDat["VacDat"] = vacDat
    saveDat["PlayDat"] = playerDat
    saveDat["Storage"] = storeDat
    saveDat["MatDat"] = matDat
    saveDat["BuildDat"] = buildDat
    saveDat["RingDat"] = ringDat
    saveDat["WorldDat"] = worldDat
    saveFile.store_var(saveDat)
    saveFile.close()
   
    pass



 Everyone will tell you that you don't need the "pass" keyword. They are correct, "pass" is used to skip empty functions and does no harm at the bottom of a function. I usually start two or more functions at once and use pass so I don't get errors or red lines as I work on individual functions.

First I created the "saveFile" variable and created a new file. Then I opened a file I intended to save to. The file does not need to exist if you are writing it, godot will automatically create a new file. It is best to use the "user://" location as this is a location that the game is allowed to write to. Now I assign the different variables I want to save to a single variable I initialized at the top of the script. Then the variable is stored in the file and it is closed. Remember to close the file to avoid memory leaks.

func load_world():
    var saveFile = File.new()
    if not saveFile.file_exists("user://savegame.save"):
        print("error, no save file")
    else:
        saveFile.open("user://savegame.save", File.READ)
        saveDat = saveFile.get_var()
        cells = saveDat["Cells"]
        vacDat = saveDat["VacDat"]
        playerDat = saveDat["PlayDat"]
        storeDat = saveDat["Storage"]
        matDat = saveDat["MatDat"]
        buildDat = saveDat["BuildDat"]
        ringDat = saveDat["RingDat"]
        worldDat = saveDat["WorldDat"]
    saveFile.close()
   
    pass


Now to load the data back. First we need to create a variable and open a new file. Variables initialized in a function can only be used by that function. Next, check to make sure the file actually exists, since we are getting data from it. I don't check to see if the file has any data since it should be in there.

Open the file and assign the data to another variable, the one initialized at the top of the scrip should work. Now we just apply the different key values to their respective variables. I'm not sure if different keys are passed by reference, but I think it depends on the variable's type. Finally, close the file to prevent memory leaks.

Feel free to reference godot's save tutorial if you want to try different ways of saving data.