Support Me on Patreon

Showing posts with label godot engine. Show all posts
Showing posts with label godot engine. 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.





Friday, April 17, 2020

Eclipse

This post will contain gamedev tips, some concerning Godot, after my depressing rant. I'll pound the area around the rant with some octothorpes.


###   ###   ###   ###
Shortly after the corona virus restrictions went into place, my laptop died. First the HD, after I replaced that the wireless and memory failed. In the end my HP laptop fully failed and I lost most of my files. Thankfully, I had backed up the most important files.

I pieced together a desktop running windows 7 for now. I don't have the money to get internet access where I live, and last I checked I don't get service here anyway. I live in a dead zone and have to choose specific phones and services to even get a small signal. After using my phone at a WI-fi hot spot in town to gather drivers and service packs, I was able to run the godot engine and play some games. During some gameplay on my cousin's Xbone, we discovered his phone gets signal in my room, in a very specific area. I'm now connected to a hot spot that isn't much better than dial up.

I'm going to gather my files and try working on games again soon, but with my more limited resources, I'll have some difficulties uploading updates until I can either get better internet or a laptop. It doesn't help that my focus seems to cause delayed chest pains. Since I have no idea how to avoid that, I must fight my own coping methods, ignore the pain, and push myself. While not the best idea, I haven't many other options.


Aggression is great for forward momentum. More dangerous and stimulating than coffee.

###   ###   ###   ###

Since I'm slightly depressed I guess, not feeling myself, I'm going to take a break from Little One and fiddle around with Godot some. I'm interested in procedurally generated maps, mostly 2D tile maps. There are great tutorials on using noise to make these maps, mostly.

I found using the help search in the script section of the editor rather useful. Mainly I just generated a flat map that sets either dirt or stone based on the height. This is slightly randomized and doesn't use noise, but noise could be used. I've got a function that makes noise for the caves and removes tiles based on the value when I get the 2d noise of an area. It has seriously reduced the amount of code I need and the map looks better.

For ores I'll be using different noise, choosing an area, and setting ores by height. Overlapping the ore heights will make things look more natural. I'll mostly be replacing solid blocks in chosen areas, with numerous areas randomly sampled or sampled through another method. Once I have the noise modified the way I want, I'll use different noise to shape the hills.

The map will be in three layers; land, fluids, and backgrounds. Fluids will be randomly placed and filled, but will also rely on the land map for placement and flow. Trees and plants might be on the BG area. I'm not concerned with good-looking details, and much of the gameplay will be a mix of minecraft (water,trees), starbound (mining, tools) and terraria (combat, weapons) with some mechanics from interesting mods and myself thrown in (tool modifiers, bombs).

For falling blocks (sand, gravel) I'll most likely remove the tile and add a kinematic object that becomes a tile again once it stops falling. Liquids will be handled as closely to minecraft as possible. Block placing will remove liquids and infinite pools will be planned. Mostly this is because I'm lazy and I don't think godot has fluid dynamics.


There are ideas and plans for this project, but for now it's just me tinkering. Now for some tips.

The noise seed can either be randomized, or you can use a specific world seed.

Write different noise functions to generate noise for different parts of map generation.

Creating functions to generate noise based on parameters will allow easy modification.

Tile Maps can use kinematic physics, or the parent  node's physics. This should allow an area to be used for the liquids.

A tile map's tile set can be changed or modified during game play.
 Swap a tile and nobody cares, swap a sprite in the tile set and the whole map updates.

"invx128y32" Use similar keys in a dictionary of inventories to keep track of chests at almost any position. I just hope some player doesn't try filling the world with chests. X & Y should correspond with the chest's position.

If the map is modified by the player (mining, bombs) write a function to check surrounding tiles for any actions they need to take (flowing, falling).

Liquids should try flowing down first, then sideways. I'll most likely place iquid tiles below and flow tiles to the side

Create dictionaries and lookup tables to keep track of tiles and what can affect them.


And finally:

Map generation can take some time with all the loops and actions. Rendering the map as it is generated can cause even more lag and freezes.

Set the tile map's visibility to false before generating the map, then back to true after. The map generates far faster with no visuals.






Tuesday, February 25, 2020

Animations can go bone themselves.

Skeletal animations tend to have some drawbacks. Aside from being one of the biggest drains to framerate, creating them is as complicated as modeling a 3D character. Once the skeleton is made, and the object skinned to it, creating the keyframes can be a bit daunting. Creating the animations isn't too hard, with a few tips.

0: doing things by the tens:
You only need to make a keyframe at specific intervals. I suggest every five to ten frames. (1,10,20,30,40) 

1: Most things can be done a few bones at a time:
Head bobbing and tail wagging can be done after the major (walking) animation is done. This also goes for arm swinging.

2: ANIMATE ALL THE LEGS!:
Yes, do them in pairs. Each leg of a pair should have the same exact animation, but each pair should have a different animation. Front pair of legs should cycle forward while the back legs cycle back. Then just grab opposing (front_left, back_right) and drag them back two keyframes. Then take the keyframes that hang off and move them to the front. This offsets the leg animations.

3: Bugs are not that hard:
For 6-8 legged creatures, assign pairs of legs to a bone. Assign the front and rear left legs to a left bone, then the middle to a different left bone. For spiders, left legs 1&3 to one bone and 2&4 to another. Now just animate those bones like you're rowing a boat. Simple and creepy.



Of course, when you import them to a game engine, they can still get wrecked.

Remember to have the mesh and skeleton centered (world and object) properly to avoid some pitfalls.

If the characters need to be rotated, apply transforms and delete older versions of the export and import files (to be safe).

If it works, save the animations files before you break it.

Keep the hierarchy as much as you can when preparing the actual character for use in-game.

Keep calm, or find a punching bag.









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


Friday, January 3, 2020

A Fungus Among Us

I'll be starting on my two-month project, but it may actually take three or four. It's a sci-fi "horror" game called "Blue Bloom". You'll have to clean a planet of an infectious, parasitic, fungus while stationed upon an island. This means that most clean-up efforts will be long-range. Cures will have to be analyzed and built via a crafting and modular building system.

This project will use resources from my two previous projects, along with adding more resources. while it will draw from previous experience, I'll be learning new things as well. Currently I'll be setting up a basic player and testing distance. I'll be adding a LOD system to this game for optimization. I think large faces render slower when they are close to the player, so this should break that up.

There will be several different spawn caps for creatures, both soft and hard. The soft cap is just for normal spawning, while the hard cap controls "event" spawning. Since creatures may be spawning in/out regularly, I'll be using signals to coordinate the spawns; reducing lag. This entire project is me seeing how fast I can put a game together when I have numerous resources.

Little One will still be worked upon, and updated. Many ideas from that game will be adapted for Blue Bloom. Not only the vacucell, but the crafting materials as well. A few materials will be added in Blue Bloom, making the count about twelve or more. If I use preexisting resources, most of this project will just be coding.

The map for Blue Bloom will be comprised of smaller scenes, also comprised of smaller scenes. Each map piece will be made of cells. The idea is to make a handful of specific cells and use a lot of them to build the map pieces. These pieces will be controlled via scripts to change their mesh or visibility as needed. I think the map will run a bit faster if I set the cell visibility even outside the player's view. I'm not sure if the creatures will have navigation abilities, but I'll try to include that from the start.


The map will be 8x10 areas in size and the areas might be roughly 10x10 cells. That's 800 scripts running a loop of 100 each frame to handle cell visibility, or is it? If I only check one cell per frame, I eliminate all those loops. The script can get through all the cells in 1.5-3.4 seconds (depending on frame rate). This will cause some problems with low-frame rate or lag.

While a single script could handle all the map areas, iterating all the cells of all the map areas every frame or X-frames could cause lag. To reduce even more lag, I might just check the nine map areas around the player.
To do this, I'll probably surround each map area in an area node and give them all grid coordinates. When the player enters an area, the current grid coords will be changed and I can write a script that organizes and acquires the map areas.

Creatures will change their own animation progression and visibility since they'll all have scripts. They should spawn within a pair of ranges from the player, to be changed by other factors. Any critters spawned will be direct children of their spawner and should only travel a set distance from their parent before returning/despawning. To keep the pressure on the player, I'll be playing fast and loose with the spawns.

Major hard points will include the sky, navigation, creatures, collision shapes, and map handling. I'm in no way ready for this project, but I'll be doing it anyway.

















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 27, 2019

End of the Month Plan

I've been adding the menu systems in Little One. So far, the parts needed to win the game can be crafted, so can player upgrades. Stats, materials, and parts can be checked in the menu, and there is a save button. Now I just need to add the part objects and material and part dispensers so they can be collected. Several of the parts use a ton of materials to craft, so those will be retrieved via deployable drones.

The critters are modeled and textured, but have no animations. I might be adding them into the game late. Beasts may have to wait until much later to be added, along with difficulty. Opening and ending images need to be created, probably vectors that will be used like a comic to illustrate the story.

There are many things I want to add, and may add later if I have time. Changing the music for each area, allowing music to play during menus, difficulty, beasts to fight and get resources from, ship interior and monoliths. I'll add these features if I have time while I'm doing a new project next month. My main goal is to make Little One beatable and add the story elements.

NPC dialog is in the game, but I'll be modifying it to output different dialog from dictionaries. This will give the player tips, as well as adding some character to the NPCs. Most of the dispensers are done, and much of the coding is also done. I'll be setting up the last mechanics by copying needed code and modifying it. Actually, I might just take the mat collector/storage for collecting parts and dispensing built drones. One less thing to model/create (It's really just a collector attached to a giant egg).

Little One took longer than I thought, but it was interesting and I learned a lot. It has also given me numerous resources to use in my next project, and I can modify those objects for more resources. The next project will use many things from Little One, but it will have many new additions. This will allow me to reuse many elements and mechanics from Little One, making creation faster and easier.

I'll probably make a sequel or two later on.

The Next Project:

Blue Bloom will be a game full of monsters, crafting, and adventure. Using different items, you'll be able to modify the function of different workstations.  Different workstations may even assist each other. Hydroponics allows the player to grow needed food indoors, while the repellent globe wards off vicious monsters.

The vacucell from Little One makes a return, and may have extra upgrades. Joining it are numerous weapons to insure your survival, or hinder it. Modify your environment suit for different challenges. Repair laboratories and get them running again for extra advantages. Use the technology at your disposal to help clear out an invasive fungus.







Tuesday, December 17, 2019

Yadda Bla Bla Bla Bla







Dialog systems tend to be as complex and as varied as inventories. Once you've created one, others are easier to make. Giving the player choices, branching dialog, or changing variables from the dialog system all make it more complicated. Little One's dialog system is just going to be a direct info dump. There will be text, and a done button when you are finished reading.

Godot has two of my favorite nodes ever, EVER!. The resource preloader contains assets for later use so you don't have to write all the paths out. The rich text label is a force unto itself. With BBCode, word wrap, scroll bars, and metadata links, you only need this node for dialog output. Text can be set as a meta-link that can pass a value via a connected signal. You can then do various things depending on the meta value passed.

My main dialog output setup consists of a panel with the rich text label as the child. The panel has the script, but the rich text label does all the work. I usually set a custom font since Godot only has one tiny, terrible font. The meta link is underlined by default, but I add BBCode color and center it to make it more visible. Several meta links can be added to the dialog and consist of the data passed and each attaches to the next text or BBCode string added.

The worst part of a dialog system is actually creating the dialogs. I'll be using a preload script with dictionaries and functions to randomly select text strings. Day zero will mostly consist of hints and tips for the game. Just make sure that if you pause the scene, you don't pause the dialog output.

I usually connect a signal from the player to the NPCs and from the NPCs to the player. If you have limited NPCs and everything is grouped correctly, this can be done at the start of the level/game. If the NPCs are numerous or randomized, this can be done when you interact with the NPC. Just remember to check if the signal is connected, godot doesn't like reconnecting existing signals.

With this basic setup I signal the NPC (and pass a value so only that NPC answers) to talk. The NPC then gets the text and signals the player with the required information. Now the player passes the data to the dialog system to format and output the text. I've started just calling a function from the dialog system in the player's script. Since I've learned that you can just call the functions from a node's script I might connect and use signals far less.

Direct-calling functions might replace generated signals, but it cannot replace all signals.





Tuesday, December 10, 2019

Doing things by half

Lately I've noticed something odd in the godot engine. My framerate dipped to 20fps and the max for an empty scene was 30fps. Sure, I've been adding stuff to Little One, but that frame drop was uncalled for. Clamping the framerate at 30fps was a bit unusual, so I did some digging.

Checking my laptop's processor in the task manager, I noticed that only half of my processor's power was being used. I'm pretty sure this was new. My screen's refresh rate was set at 60Hertz, so that wasn't the problem, or was it. Looking on the internet, I found a solution that worked; but I had to change a couple registry values.

Little One's frames went back to full, but "full" is still 30fps. Somehow the refresh rate indicated in the graphics settings is not the rate of my actual computer. With vSync on, godot runs at a max of 30fps. Without it, it could be more, but it still seems to be 30fps. Even with my processor now running at full, I'm still mired at 30 fps. I'll be checking my graphics drivers to see if I need to update.

Either an update fouled something up (most likely), or this is intentional. Why would Microsoft truncate the processing power of a computer? Is it to keep the PC from overheating or crashing? (LOL, I doubt that) Could it be because my laptop is over three years old? I'd assume it's because I have an AMD processor, but intel processors are also being slowed.

Personally I despise my laptop's speed being reduced which is why I messed with the registry settings. The hobbled refresh rate is another matter, but that's difficult to notice unless you're an indie dev.

Speaking of Little One, I've been editing the maps to make them easier to navigate (at all). I'm also testing out shadows, may have to add a flashlight. The caves should be navigable and the spire fields are actually explorable. The player model is in and has animations, but I'm not using the animations yet. I might have to refactor the player or create a secondary version, but that can wait. There are gates to destroy throughout the map, and their destruction is saved with the game.









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.











Tuesday, November 26, 2019

Grain Drain

I added a save function to Little One. Most of the data was just easy to write to the file, but the buildings had to be formatted. Writing the dictionary for the buildings didn't take long, but I've had to add values throughout. A dictionary for the wild plants was also needed. Then I had to make sure the build platforms saved their own values while the buildings saved their values.


The fields seemed like a good start, both wild and domestic. They mostly went off without a hitch, but I had some bugs when I programmed out an exploit. Storage was next, and I gave it little thought before moving to the critter pens. Those pens had a few bugs, but the critters were missing. I had to modify the re-parenting function so they'd work, but the critters never seemed to load. Turns out, they did load, but kinematics and rigid bodies don't like each other and critters got flung.

Last night I checked to make sure everything was working, and the storage buildings were not. I was trying to get values from an empty dictionary within a dictionary. Putting the storage cell generator in the global dictionary worked, but I had to modify a few things. Today I added a few new grain plants just for something new. Most of the plants are modeled, but I need to tweak them.

After all that, I'm going to rest before I add more content. This whole project has taught me valuable lessons I'll carry into the next project.

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.











Tuesday, November 19, 2019

The Rain in the Game Falls Mainly on Nothing?!

There are many ways to do rain and other weather effects. Some games use particles, which can clip through objects. A few just add/remove objects, but the physics needed and constant object flow causes lag. In 2D it can just be a screen effect. A few use shaders or have dedicated weather systems. For newer developers, that don't have the resources or experience, rain systems can seem awkward.

Either you have particles or objects, but those either clip through objects, or cause lag. I've found another way. First, a little advice and an example. Everyone seems to think the rain needs to fall, preposterous. Take two coins, fairly new ones, and stack them between your thumb and pointer finger. Now rub the coins together, slowly getting faster. If done correctly, three coins should be visible. It's an optical illusion, the same as an after-image that some anime characters can create.

How does this help us create a rain system? By taking several rain meshes and shuffling them around the player, we can cause an illusion of rain. I'll walk you through the steps.

First, make two rain objects, a drop and a splash. We'll add them to a parent object/node as meshes with a basic water or blue texture, no colliders or transparency needed, just meshes. I like to add each to a different group or have some other way to grab them from code. Don't try to grab them directly or through paths, we're going to copy them. The scene should be a parent node with a few dozen drop/splash children.

Make a few dozen copies of the drops and splashes. Add the scene to a scene, preferably as a child of something positioned at (0,0,0). Now let's create a new scene with any positional node. Since I'm doing 3D I'll use a spatial node. This can also work in 2D with minor adjustments. Add a raycast and make sure it is casting down (-y) by about 300.  Move it up to +y 200/250, make sure it is active as well. Create copies and change their x/z to whatever you feel like. Keep them relatively close to the center, but not on the center.

About 12-32 raycasts should be good. Add a script to the top (parent) node. The scene should be a parent node with a few dozen raycast children. On ready you should get the splashes and drops from the scene tree using groups. If you've added the raycast scene to the same parent you added the drops scene to, you can just get the parent and then the drops scene's children. Either way is good.

Get the raycasts as well, you can just add the children to a variable. Get the player node/character as well. You should have two main functions, shuffle_rain and unshuffle_rain. The unshuffle_rain function should just get all the drops/splashes and place them somewhere hidden. I suggest changing their translation to (0,-200,0).

The shuffle_rain function is a bit more complex. Grab a random raycast, drop, and splash. Check that the raycast is colliding and get the collision position. Place the splash at the collision position, and the drop at a higher position. You can add a random number to the position's Y axis.  You would do this several times a frame, feel free to experiment.

The final things to do is to get the raycast parent to rotate and change it's X/Z translation to that of the player. Randomizing the Y rotation can help make the rain move more randomly. Now all you need is signals/Boolean to start/stop the rain.

No odd clipping, no lag, no physics, easily editable. It's a good rain system if you want something easy to implement.















Monday, November 4, 2019

A Small Matter

It always seems like two steps forward, one step back when you are a singular gamedev. I'm having problems with the textures/materials in Little One and there is still so much to do. Sometimes I wish these problems didn't happen, but I enjoy solving problems. Once the material problem has been corrected, and I know a good way to correct it, I'll start adding and testing the final mechanics.

The dialog system is in another project and needs to be modified for Little one. Player and NPC models are mostly done, just need textures, animations, and a few minor accessories. Critters need some more programming and they'll give way to beasts within the game. Building upgrades need to be modeled, textured. and fully implemented. There needs to be a way to dispense materials from destructible objects. Many of the parts and player upgrades need to be coded and implemented. Opening and ending scenes need to be done along with success/fail conditions. World data and save/load systems need to be finished.

I should do some planning on the final parts needed. Most of the player upgrades are partly implemented. There is a collection on open game art that has resources for Little One, as well as what I'm making now.

Speaking of planning, I'll be planning a project a bit this month. If I finish Little One this month (November 2019) I can work on another project in December. Little One will have taken about five or six months at the end of November 2019.

I wonder if I can make a bigger game in two months if I planned it well.

Monday, September 30, 2019

Node of Command

So I told the build menu, to tell the build system, to tell the building; to upgrade. This all while the game was "paused". Any node with a script is able to get another node to run functions within their script. Something like node.function() where node is the node that has the function, and function is the function. Clear as mud until you try it.

This is great in situations where signals may be too troublesome to set-up. I'm not talking about default signals, but custom connections. It is also helpful where you can get or pass a node with w function you want to run. Not sure if you can run a node's functions on another node, but if I can I'd probably crash the engine every day. Might try it just to check.

The game is never truly "paused". Pausing the scene tree in godot just pauses processing functions (process, input, physics). Signals and calling other nodes' functions from an active node still works. (Running the _process function on a node from an un-paused menu node might crash godot) This means I can cause NPC expressions, object building, and general mischief while the game is paused just from a single active node. Cascading function calls anyone? (How to mess with the player, 101)

Arrays (really?) and dictionaries are passed by reference, not copied. This means that if a node's script sets a dictionary as equal to another dictionary, changes are synced across all instances of this dictionary. So my silos will grab the parent's exported dictionary which will be referenced from a global building dictionary (or even a nested dictionary). So updating the silos when you add/remove items will update the master dictionary.

And there are still tricks to find.