00:00
00:00
Gotzzavanken
Gothic barbarism, sometimes in space.
Cartoons are for adults. I enjoy working different styles.

Artist & GameDev

Joined on 10/14/22

Level:
11
Exp Points:
1,282 / 1,350
Exp Rank:
52,786
Vote Power:
5.34 votes
Rank:
Scout
Global Rank:
36,158
Blams:
48
Saves:
212
B/P Bonus:
4%
Whistle:
Normal
Medals:
21

Gotzzavanken's News

Posted by Gotzzavanken - January 17th, 2024


Hello Hello, hope you are doing nicely! While not my first time doing a DevLog, it is my first one here on Newgrounds!


My body demands rest, which is boring, and I have stubbornly refused to concede. This has reduced my productivity and set me behind schedule, I should probably care about my health a bit more. In any case, lets go straight at it!


At the start of the weekend I was working on the project and wanted to refine how items and bullets are managed. To recap, in the previous installment, the items were set as different scenes but all of them shared the same class script. Same code file being used for the each item scene. Was fine but I wanted to use one code file and only one item scene which would change all its values based on the selected "item_type" exported enum.

After setting it all up I tested it, everything was working but had issues with instantiated object's resources not being local, so every time an object of "class A type 1" was spawned: all "class A" objects already spawned would change their type to 1.

Instead of trying to change the resources to operate locally I went straight into a new, separate, project to experiment with Godot's custom resources. Read the Docs, watched a few videos. Fairly intuitive and similar to what I had already done in the previous game. On top of that this would in theory boost performance too, so... n i c e.


I could go into the details but, why?


iu_1148563_12227425.gif


The implementation itself has nothing to do with what Im gonna use it for (In the future I will for sure), the inner mechanics of it are what matters.


Okay okay I'll explain a bit xD, it's no big deal:


First, you create a script that inherits from "Resource" and in the code you'll class_name it with however you wanna call it. At this point you can begin variable declarations for what your resource will store. The resource is meant to be data that is loaded and read by other scenes, in the case of this experimental project the variables were item's name and the item's SpriteFrames (which are a resource used in AnimatedSprited2D nodes). But you can obviously set it with whatever amount of variables, and of any type, you want.


item_resource.gd script:

##This is an item resource, holds all the data for items
extends Resource
class_name item

@export var item_name : String
@export var item_gpx : Texture2D
@export var item_gpx_region_rect : Rect2
@export var item_sprite_frames : SpriteFrames

At first the items were regular sprites, left those extra variables for the luls


After this we can go to the file system, create resource, search for the name you set with class_name and BOOM


iu_1148562_12227425.png


Once that you create it you can double click it on the folder you saved it and all the variables you exported in the script will show up in the inspector:

iu_1148561_12227425.png

Don't forget to save after editing anything there.


So this is a template now and all you would need is to make more resources of type item (in this example) and give each one the corresponding values. Notice that giving a value to the variables will give them a default for when you create them. In the picture above you are seeing it after I edited it, when first opened it was empty.


The second step is to create the actual item scene which will load the data. Fairly simple. Make a scene, in this case the root node was an AnimatedSprite2D, and add a script to it. I called mine "item_scene", added an export var to accept the resource and a function to set the scene's SpriteFrames to be the ones from the loaded item_resource.


item_scene.gd script:

extends AnimatedSprite2D

@export var item_resource : item

func _ready():
    set_info()

func set_info():
    self.sprite_frames = item_resource.item_sprite_frames
    play("default")

I also made SpriteFrames resources, once for each item, which are loaded into their respective item_resource files.


The third step, and here my project is deviating from what Im gonna use in the game, made a singleton to preload the item_scene and the item_resource. The latter in an array:


G_LOADER.gd script:

extends Node

@onready var item_scene_preload : PackedScene = preload("res://item/item_scene.tscn")
@onready var item_resource_files : Array = [
    "res://item/item_diskette.tres",
    "res://item/item_healthpack.tres",
    "res://item/item_multishot.tres",
    "res://item/item_speedpill.tres"
]

Don't forget to add your singletons to the autoload list.


Finally, when instantiating the item, I set the resource to be loaded by the instanced scene, and in my case the resource was picked by randomly choosing an item from the array in the G_LOADER:


Level scene script:

@onready var spawned_items_layer = $SpawnedItems #A node in the sceneTree

func spawn_item():
    var item_to_spawn = GLoader.item_scene_preload.instantiate()
    item_to_spawn.position = get_viewport().get_mouse_position()
    item_to_spawn.item_resource = load(random_item_resource())
    spawned_items_layer.add_child(item_to_spawn)
    print("Item name: " + item_to_spawn.item_resource.item_name)

func random_item_resource():
    randomize()
    var random_item_resource_selected = GLoader.item_resource_files[randi() % GLoader.item_resource_files.size()]
    return random_item_resource_selected

A nice thing I noticed is that you don't need to set a variable within the item_scene called "item_name" and set it to the resource's "item_name" (which we did do for the SpriteFrames). You can call the information directly from the loaded resource, in this case with the code you see at the print method.


The only thing I'm not sure is why are there 1240 objects when doing nothing O_O


Real-Time monitors:

iu_1148573_12227425.png

Everything else was pretty nice though :)


So, long story short is:

  1. A custom resource will carry data (item variables)
  2. A scene with a variable that loads that type of data (@export var item_resource : item)
  3. When you instantiate the scene you gotta load the data into it
  4. The scene (scene with sprite node from point 2) will work whatever code you got that interacts with the data


There are countless of ways to use this which will depend on the purpose, sometimes you might not even need to load the the data into the instance because yours might be set to have a specific resource from within their own scene as an @export var.




And we have reached the end of this post, while it might not be showing you how the game is going to look, there are some spoilers you may catch! Thank you for following me in this half DevLog half tutorial about using Godot's custom resources.


Mortemforge's Elven Lethal Operations B is on the works and better than before, I honestly don't want to set a publish date again xD Unless something goes wrong, it should be ready next week, praise the gods. The time Is 23:23 and I feel I'm forgetting something... well, it'll have to do for now! ;)


Hugs!


Tags: