Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411423 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 18, 2024, 08:53:56 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsHyper Light Drifter: Experience rebuild
Pages: [1]
Print
Author Topic: Hyper Light Drifter: Experience rebuild  (Read 5707 times)
Mr.Kitty
Level 0
**


View Profile
« on: July 07, 2018, 03:56:09 AM »

Introduction
Hi, guys! I'm indie developer(absolute beginner). This devlog is created for beginners like me. The main idea is not to create something but to share dev experience from absolutely beginning. I think it's interesting and ultimate useful(for absolute beginners) to look at the way of some dude that go from zero to confident game developer. So I'm this dude, welcome.


What you will see
My starting point is to recreate part of Hyper Light Drifter. Here I'll post all steps of developing process with all explanation: all code, sprites and etc. At the same time there will be a youtube channel with short "briefing" of what I've done. Also there will be other information, that I wont post here.


Plan
Here is my goal - recreate main city + west part.



This location the most easy in Hyper Light Drifter: art is less complex than from other locations and AI less complex as well.
What will be recreated(planning now, maybe list will become longer):
  • Movement system
  • Battle system
  • All sprites(mostly) and other textures
  • AI of base enemies + BOSS
  • Graphics features(?)(pretty hard, I guess)(particles and etc)
  • Saving and loading system
What I have now(will be updated regularly)


Updated(20.09.2018)

I will work with TWO engines
First is GMS2, second - Godot. Page with developing on Godot will be created in a few weeks after some learning of this one.

Feedback
I'll try my best to answer every question you ask. If you have any thoughts to improve my developing process, how to fix something or anything like that - write, it will be helpful for everyone. Hope you guys find this devlog useful.


My GitHub repositories:
« Last Edit: November 08, 2018, 10:44:27 PM by Mr.Kitty » Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #1 on: July 09, 2018, 05:47:33 AM »


1) How character moves
2) How character jumps
3) How sprite changes during moving

----------------------------------------------ONE------------------------------------------------------
First and second points are connected to each other. That's because I use finite state machines. Make long story short, object changes it's state depending on what button you press. At the very beginning player object(later just player) is in move state. So if you press any move button, player moves, but if press space button, player's state changes to jump state, player jump and after that returns to move state.

Well, let me show you how it looks in code.

We have enumeration called player and variable called state_ which contains player's state

Code:
enum player {
//Player states
move,
jump
}
starting_state_ = player.move;
state_ = starting_state_;

There are two states: move and jump. Code of our states is located in different user events.



Depends on in what state we are now, we run user event we need.
Running user events is in step event.

Step event:
Code:
event_user(state_);

The "main state" is move state, because from this state we go to other states. If we press space button we go to jump state. After, jumping state automatically returns to move state.
That's all for state system. Let's go to move state.

Move code(this code is in user event 0):
Code:
/// @description Move State
var _x_input = keyboard_check(vk_right) - keyboard_check(vk_left);
var _y_input = keyboard_check(vk_down) - keyboard_check(vk_up);
var _direction_degree = point_direction(0,0,_x_input, _y_input);
//direction where we go now

var _x_speed = lengthdir_x(speed_, _direction_degree); //get necessary y and x speed values
var _y_speed = lengthdir_y(speed_, _direction_degree);

if (_x_input == 0 and _y_input == 0) { //player stay
image_speed = 0;
image_index = 0;
}

if (_x_input != 0 or _y_input != 0) { //player moves
direction_facing_ = scr_get_direction_facing(_x_input, _y_input);
//check move direction to change sprite
image_speed = 1;
if(_x_input == -1)
image_xscale = -1;
else
image_xscale = 1;
x += _x_speed;
y += _y_speed;
}
In first to rows we get kind of coordinate moving direction depends on what buttons we press. If we move left _x_input = -1, if right - _x_input = 1. The same with _y_input. After we get X axis and Y axis parts of our "speed vector", because if we just add speed in necessary direction and move diagonally, than we move too fast and it looks weird, that's why we want to get X and Y component of our speed in direction we need. In general, that's all.
----------------------------------------------TWO------------------------------------------------------
Briefly. Player get some speed value and direction for moving. Speed gets lower by subtracting some small value until player stops. When player stops, state changes to move state. At the same time I create player copies on position player moved from. After some little time these copies moves to player's position by the same way.
Code(user event 0, move state):
Code:
if (keyboard_check_pressed(vk_space)) {								//expression to jump
clone_move_direction_ = point_direction(x,y,mouse_x,mouse_y);
scr_set_move_values(self, clone_move_direction_, 6, 0.3);
previous_x_ = x; //coordinates where clones will spawn
previous_y_ = y;
clone_count_ = 0; //current clone count
state_ = player.jump; //change state to run user event 1
}

At first we need to get direction where to move. We move to our mouse. This script scr_set_move_values is setting values for the next script that moves player. We remember our previous coordinates and than switch to jump state.

scr_set_move_values:
Code:
///@arg object
///@arg direction
///@arg speed
///@arg friction

obj_ = argument0; //object that will be moved
move_direction_ = argument1; //direction
move_speed_ = argument2; //speed
friction_ = argument3; //value we will subtract from move_speed_

Code(user event 1, jump state):
Code:
/// @description Jump State
scr_move_object_to();
if(clone_count_ < 2 and alarm[0] <= 0) {
//create player copies that will follow him
instance_create_layer(previous_x_, previous_y_, "Instances", o_player_jump);
alarm[0] = global.one_second/20;
clone_count_++;
}

if (move_speed_ <= 0) //get back to move state
state_ = player.move;

Here you can see some script called scr_move_object_to. This script moves player.
Below script is code that creates 2 player copies every 1/20 second.

Let's look at scr_move_object_to:
Code:
var _x_speed = lengthdir_x(move_speed_, move_direction_);
var _y_speed = lengthdir_y(move_speed_, move_direction_);

if (move_speed_ > 0) {
obj_.x += _x_speed;
obj_.y += _y_speed;
move_speed_ = scr_approach(move_speed_, 0, friction_);
}
We get X and Y component of our speed in direction we need, like in move state, and move our player while speed > 0.
Script scr_approach just helps reach some value.

scr_approach:
Code:
///@arg value
///@arg target
///@arg friction

var _current = argument0; //starting value
var _target = argument1; //value we want to approach to
var _friction = argument2;

if(_current < _target)
return min(_current + _friction, _target);
else
return max(_current - _friction, _target);

Well, when our "jump speed" approaches 0, we get back to move state.
Let's look at object of player copies.



It's primitive object. It just creates, moves to player object after some time and then destroys itself.
Create event:
Code:
scr_set_move_values(self, o_player.clone_move_direction_ , 6, 0.3);
allowed_to_move_ = false;
alarm[0] = global.one_second/30;
Step event:
Code:
if (not instance_exists(self))
exit;

if (allowed_to_move_ == true)
scr_move_object_to();
if(move_speed_ <= 0)
instance_destroy();
Alarm[0]:
Code:
allowed_to_move_ = true;

----------------------------------------------THREE------------------------------------------------------

Sprite changing based on direction player goes. In create event of player object I've created enumeration called dir(direction). Here is all create event code:
Code:
speed_ = 1

enum dir {
right,
up,
left,
down
}

enum player {
//Player states
move,
jump
}
starting_state_ = player.move;
state_ = starting_state_;

direction_facing_ = dir.down;

sprite_[player.move,dir.down] = s_player_run_down;
sprite_[player.move,dir.right] = s_player_run_right;
sprite_[player.move,dir.left] = s_player_run_right;
sprite_[player.move,dir.up] = s_player_run_up;

sprite_[player.jump,dir.down] = s_player_run_down;
sprite_[player.jump,dir.right] = s_player_run_right;
sprite_[player.jump,dir.left] = s_player_run_right;
sprite_[player.jump,dir.up] = s_player_run_up;

All player sprites are contains in 2dimensional array called sprite_. This array helps as change sprite automatically in step event depends on in what direction player moves and what state now is (I don't sure if it is correct to say "now is", correct me if it is incorrect. Hope you understand what I mean).

Step event:
Code:
event_user(state_);
sprite_index = sprite_[state_,direction_facing_];
depth = -y;

How do we know what direction now is? Let's get back to move state.
User event 0(move state):
Code:
/// @description Move State
var _x_input = keyboard_check(vk_right) - keyboard_check(vk_left);
var _y_input = keyboard_check(vk_down) - keyboard_check(vk_up);
var _direction_degree = point_direction(0,0,_x_input, _y_input);
//direction where we go now

var _x_speed = lengthdir_x(speed_, _direction_degree); //get necessary y and x speed values
var _y_speed = lengthdir_y(speed_, _direction_degree);

if (_x_input == 0 and _y_input == 0) { //player stay
image_speed = 0;
image_index = 0;
}

if (_x_input != 0 or _y_input != 0) { //player moves
direction_facing_ = scr_get_direction_facing(_x_input, _y_input);
//check move direction to change sprite
image_speed = 1;
if(_x_input == -1)
image_xscale = -1;
else
image_xscale = 1;
x += _x_speed;
y += _y_speed;
}

Don't look at _direction_degree, we need it to get Xspeed and Yspeed. In second if statement you can see script scr_get_direction_facing. This script gives us the information about the direction we move.

scr_get_direction_facing:
Code:
//@arg x_input
//@arg y_input

var _x = argument0
var _y = argument1

var _direction = round(point_direction(0,0,_x,_y) / 90)

if _direction == 4
_direction = 0

return _direction

It works the same way like getting _direction_degree, but here we divide degrees by 90. That is to say that we divide our trigonometric circle to 4 parts, like 4 direction: right, up, left, down. After getting this direction we need to correct this value, because 4 and 0 are the same directions. After all of this calculations we get necessary sprite in step event.

Also some words about this block of code(user event 0, move state):
Code:
if (_x_input == 0 and _y_input == 0) {								//player stay
image_speed = 0;
image_index = 0;
}

if (_x_input != 0 or _y_input != 0) { //player moves
direction_facing_ = scr_get_direction_facing(_x_input, _y_input);
//check move direction to change sprite
image_speed = 1;
if(_x_input == -1)
image_xscale = -1;
else
image_xscale = 1;
x += _x_speed;
y += _y_speed;
}

First if statement works, when player doesn't move, so we need to stop animating and set first frame of sprite as default. Second statement works when player moves, so we need to continue our animation(image_speed = 1) and check our direction on X axis. Depends on what direction on X axis we have we rotate our sprite in necessary direction(image_xscale).
Logged

Juju
Level 0
**


Grumpy Pug


View Profile WWW
« Reply #2 on: July 10, 2018, 01:11:20 PM »

I'll be stopping by from time to time to see how you're getting on.
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #3 on: August 01, 2018, 06:26:13 AM »

Hi everyone! Now I'm resting on a sea and can't write a review of my current code. So you can see it on youtube.

Here I talk about artificial intelligence and new Attack State for the player object:




Hope you enjoy.

Next update will be after 10 days.
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #4 on: August 11, 2018, 04:09:03 AM »

Hi, dudes. Something terrible happened in my family and for now I can't continue working on the project. BUT dont forget me, I'll try my hard to continue working as soon as it is possible.
Listen guys, for now I need to start working on my science project to get financial independent. I dont know if I can work on HLD and science at the same time, but for this moment I need to focus only on a university work. Maybe things will be not as hard as I imagine and I'll start working on HLD at september. If not, wait me until october or november. I'm not going to quit and I wont let my dream be only a dream.
@When the time is right, you will be back.@
I'll be back, I promise.
Logged

AgentAvis
Level 0
**


View Profile
« Reply #5 on: August 11, 2018, 11:26:35 AM »

Hi, dudes. Something terrible happened in my family and for now I can't continue working on the project. BUT dont forget me, I'll try my hard to continue working as soon as it is possible.
Listen guys, for now I need to start working on my science project to get financial independent. I dont know if I can work on HLD and science at the same time, but for this moment I need to focus only on a university work. Maybe things will be not as hard as I imagine and I'll start working on HLD at september. If not, wait me until october or november. I'm not going to quit and I wont let my dream be only a dream.
@When the time is right, you will be back.@
I'll be back, I promise.

I'm sorry to hear that, hope things get better.
Never be afraid to put life first.
Best of luck to you.  Hand Thumbs Up Right
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #6 on: August 18, 2018, 12:52:50 AM »


Some words about changes in old code. I just improved moving by adding “while” statement and place_meeting() function to make player able to collide with any solid object. With "while construction" player can move to walls as close as it is possible.
Move state(user event 0):
Code:
if (_x_input != 0 or _y_input != 0) {								//player moves
direction_facing_ = scr_get_direction_facing(_x_input, _y_input);
//check move direction to change sprite
image_speed = 1;
if(_x_input == -1)
image_xscale = -1;
else
image_xscale = 1;

if(!place_meeting(x+_x_speed, y, o_solid))
x += _x_speed;
else
while(!place_meeting(x+sign(_x_speed), y, o_solid))
x += sign(_x_speed);

if(!place_meeting(x, y+ _y_speed, o_solid))
y += _y_speed;
else
while(!place_meeting(x, y + sign(_y_speed), o_solid))
x += sign(_y_speed);
}

List of changes since the last update:
1)   Player’s attack state
2)   Hitbox system
3)   Basic enemy AI
Attack state follows the same pattern as jump and move states. We press left mouse button and current state changes to attack. Look at the condition of changing state to attack.

Move state(user event 0):
Code:
if (mouse_check_button_pressed(mb_left)) {
state_ = player.attack;
direction_attack_ = scr_get_direction_attack();
alarm[1] = global.one_second/4;
}
scr_get_direction_attack:
Code:
var _direction = round(point_direction(x,y,mouse_x,mouse_y)/90);

if (_direction == 4)
_direction = 0;

return _direction;

This script just determines the location of the mouse relative to the player. That is to say, that player attacks in the direction where the mouse is.
Now let’s look at the code in the attack state.

Attack state(user event 2):
Code:
var _attack_sprite = attack_sprite_[direction_attack_];
var _target_array = [o_enemy];

scr_create_hitbox(x,y - 10,_attack_sprite,1,_target_array);

if (alarm[1] <= 0)
state_ = player.move;

Here we get a sprite for attack(4 sprites for 4 directions), set target array for hitbox and create hitbox(you’ll understand in a few minutes). That is whole attack state.

Example:

Just look at the changes in create event.
Create event:
Code:
speed_ = 1

enum dir {
right,
up,
left,
down
}

enum player {
//Player states
move,
jump,
attack
}
state_ = player.move;

direction_facing_ = dir.down;

sprite_[player.move,dir.down] = s_player_run_down;
sprite_[player.move,dir.right] = s_player_run_right;
sprite_[player.move,dir.left] = s_player_run_right;
sprite_[player.move,dir.up] = s_player_run_up;

sprite_[player.jump,dir.down] = s_player_run_down;
sprite_[player.jump,dir.right] = s_player_run_right;
sprite_[player.jump,dir.left] = s_player_run_right;
sprite_[player.jump,dir.up] = s_player_run_up;

sprite_[player.attack,dir.down] = s_player_run_down;
sprite_[player.attack,dir.right] = s_player_run_right;
sprite_[player.attack,dir.left] = s_player_run_right;
sprite_[player.attack,dir.up] = s_player_run_up;

attack_sprite_[dir.right] = s_attack_right;
attack_sprite_[dir.up] = s_attack_up;
attack_sprite_[dir.left] = s_attack_left;
attack_sprite_[dir.down] = s_attack_down;

health_ = 4;
invincible_ = false;

Now hitbox system. Briefly, hitbox is just an invisible rectangle. It has some properties like target array(entities he interacts with) and damage. When hitbox is created nearby the player(when he attacks), game engine checks if it collides with an enemy. If it does, something happens(for example, enemy loses health points).

Let’s take a look at the hitbox object.

o_hitbox’s create event:
Code:
damage_ = noone;
targets_ = noone;
o_hitbox’s step event:
if (!instance_exists(self))
exit;



if (scr_animation_ended() == true)
instance_destroy();

scr_animation_ended:
Code:
var _last_frame_index = image_number - 1;

return  _last_frame_index - 1 < image_index and  image_index < _last_frame_index - 0.1;

This script returns true when the sprite animation is on the last frame.
This object does nothing, just exists. All logic of interacting with objects is within objects he interacts with.
Now hitbox scripts.

scr_create_hitbox:
Code:
///@arg x
///@arg y
///@arg sprite
///@arg damage
///@arg target_array

var _x = argument0;
var _y = argument1;
var _sprite = argument2;
var _damage = argument3;
var _target_array = argument4;

var _hitbox = instance_create_layer(_x,_y,"Instances",o_hitbox);

_hitbox.damage_ = _damage;
_hitbox.targets_ = _target_array;
_hitbox.sprite_index = _sprite;
_hitbox.depth = -_y;

We get necessary values, create hitbox object and set these values in. That’s all.
Let’s summarize: we have an attack state, in attack state player creates a hitbox object nearby, if hitbox collides with an enemy and enemy is in target array he loses health points.
Now the most interesting – enemy AI. Firstly look at the enemy object.

o_enemy create event:
Code:
health_ = 3;
speed_ = 1;
damage_ = 1;
invincible_ = false;

o_enemy step event:
Code:
if (!instance_exists(self))
exit;

depth = -y;

if (health_ <= 0)
instance_destroy();


o_enemy collide event(with hitbox):
Code:
if (scr_is_target(other) == true and !invincible_ ) {
invincible_ = true;
alarm[0] = global.one_second/2;
health_ -= other.damage_;
}

o_enemy alarm[0]:
Code:
invincible_ = false;

That is a whole enemy object. There is no any logic within. This object is a parent for other enemies I will create in the future. I use an inheritance to share its properties with other enemies in the game to not overwrite the same code in every enemy.

I think I shouldn’t explain anything in this object but collide event. In this event, we can see a logic of interaction hitbox with an enemy. Firstly we check if the enemy is a target of the hitbox.

scr_is_target:
Code:
///@arg hitbox

var _hitbox = argument0;
return scr_is_in_array(object_index, _hitbox.targets_);

scr_is_in_array:
Code:
///@arg object
///@arg array

var _obj = argument0;
var _array = argument1;
var _array_length = array_length_1d(_array);

for(var _i = 0; _i < _array_length; _i++) {
if (_array[_i] == _obj or object_is_ancestor(_obj,_array[_i]))
return true;
}

return false;

If it is, check if it is invincible now. The enemy becomes invincible for some time if it was hitted. We need it because without invincibility enemy would take damage every frame per second.
Now on top of that, we are ready to look at the enemy’s AI.

All enemy logic is contained in o_dirk. This object looks pretty similar to the player’s object but it changes states automatically.

Quick explanation of how it behaves. It has 4 states: idle, follow, prepare, attack. It is in idle state as a default. If distance to the player less than 120 it starts to follow him, changes current state to follow. If distance to the player less than 40 state changes to prepare and enemy just stay for some time. After that state automatically changes to attack state and enemy “jump” (move fast) to the player (in the direction where the player is).

Here how it looks:

Now about code. Firstly, create and step events.

Create event:
Code:
event_inherited();

view_range_ = 120;
attack_range_ = 40;

enum dirk {
idle,
follow,
prepare,
attack
}

state_ = dirk.idle;

Step event:
Code:
event_inherited();
event_user(state_);

Finite state machines is our everything Smiley

Idle state(user event 0):
Code:
if(point_distance(x,y,o_player.x,o_player.y) <= view_range_) 
state_ = dirk.follow;

As I said, in this state enemy does nothing.

Follow state(user event 1):
Code:
var _direction = point_direction(x,y,o_player.x,o_player.y);
var _x_speed = lengthdir_x(speed_, _direction);
var _y_speed = lengthdir_y(speed_, _direction);

x += _x_speed;
y += _y_speed;

if (point_distance(x,y,o_player.x,o_player.y) <= attack_range_) {
state_ = dirk.prepare;
alarm[1] = global.one_second;
}

There is absolutely similar moving to player’s.

Prepare state(user event 2):
Code:
if(!instance_exists(o_player))
exit;

if(alarm[1] <= 0) {
var _direction_attack = point_direction(x,y,o_player.x,o_player.y);
scr_set_move_values(self,_direction_attack, 4, 0.2);
state_ = dirk.attack;
}

Explanation of scr_set_move_value and scr_move_object_to you can see in the previous code review.

Attack state(user event 3):
Code:
if(!instance_exists(self))
exit;

scr_move_object_to();

if (move_speed_ <= 0)
state_ = dirk.follow;

Here enemy just moves fast in direction where player was since prepare state.
That is whole logic, pretty simple I think. And o_dirk will be a parent for other enemies, cause he has states that most enemies in Hyper Light Drifter have(watch video).
Also enemy can hit player when collides with him.

Collide event(with o_dirk):
Code:
if (!invincible_ and other.state_ == dirk.attack) {
invincible_ = true;
alarm[2] = global.one_second/3;
health_ -= other.damage_;
}


The same pattern as enemy. Become invincible for some time and subtract health points.
For now it's all. Hope you find smth useful or just interesting:)
Next days I'll draw some sprites and try to create some enemies, maybe also improve battle system.
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #7 on: August 18, 2018, 01:02:17 AM »

Hi, dudes. Something terrible happened in my family and for now I can't continue working on the project. BUT dont forget me, I'll try my hard to continue working as soon as it is possible.
Listen guys, for now I need to start working on my science project to get financial independent. I dont know if I can work on HLD and science at the same time, but for this moment I need to focus only on a university work. Maybe things will be not as hard as I imagine and I'll start working on HLD at september. If not, wait me until october or november. I'm not going to quit and I wont let my dream be only a dream.
@When the time is right, you will be back.@
I'll be back, I promise.
I'm sorry to hear that, hope things get better.
Never be afraid to put life first.
Best of luck to you.  Hand Thumbs Up Right
Thank you! Now I'm okay Smiley Pretty fast I guess:D Sometimes things happen but it's normal. I realized for these days what go forward and never stop is and how it's important when you want to achieve something. So I'll try my hard Smiley
Logged

Alce
Level 0
***


Twitter: @Alce_X


View Profile WWW
« Reply #8 on: August 18, 2018, 05:29:34 PM »

Great to know that things got better! This is a lovely project, looking forward to watching how it progresses.
Logged

Aspiring chilean game dev. Likes artsy/experimental stuff.
Mr.Kitty
Level 0
**


View Profile
« Reply #9 on: August 19, 2018, 01:23:43 AM »

Great to know that things got better! This is a lovely project, looking forward to watching how it progresses.
Thank you! Glad to hear that somebody is interested in what I do Smiley One of the main ideas of my project is to share my experience with others. So I hope some time you'll find something useful here Gentleman
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #10 on: August 19, 2018, 09:57:40 AM »

I'll be stopping by from time to time to see how you're getting on.
Sorry for such late answer:D It's so cool that I was saw by one of the creators of Hyper Light Drifter, really. And hear it from you is really motivational for me. Thank you for visiting:D
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #11 on: September 20, 2018, 03:04:33 AM »

Hi guys! There will some information in this post about current development, new videos and new informative post.

WHERE WERE YOU SO LONG?!

Many things have happened over this month that slowed down the development process. But I'm in work, so dont worry, if somebody ever worried about that:D Development is a bit slower than before because of university, university and getting programming experience is my priority now, so most time I'll be doing learning. But I'll continue working on this project.

What will I do?

I'm planning to post at least one video per month. The same about this topic on TIG.

What about Godot Engine?

I've installed it on Linux and want to compile it with C++ module to write all code in C++. When I find out how to do this, I'll start creating the same project like I have in GameMaker now. Don't know if I will create new topic with Godot, maybe without code overview, so will see Smiley

Video format is changed!

From this moment video is an overview of logic, problems I've meet while development and etc. There will be no in detail explaining of all code in video because it takes too much time. So all indepth explaining will be here.

When will you post new video?

Try my best to post it until september end. The same about post in TIG.

Check my twitter(https://twitter.com/studios_mars), there @in real time@ dev posts Smiley
Logged

Devilkay
Level 2
**

Hi! First game-dev experience!


View Profile
« Reply #12 on: September 20, 2018, 07:46:34 AM »

no copyright problem...?
Logged
Mr.Kitty
Level 0
**


View Profile
« Reply #13 on: September 20, 2018, 08:53:20 AM »

no copyright problem...?
Nice question. I think there no problem would be, because that is not commercial project, I do this only to get experience and share it with others  Gomez It would be rather rash to make money with it :D
Logged

nathy after dark
Level 8
***


Open Sourceress


View Profile WWW
« Reply #14 on: September 20, 2018, 09:21:13 AM »

I'm not a lawyer but as far as I know: Your only way to be fully legally safe would be to ask for permission to do this from the Hyper Light Drifter team.

But, since game mechanics can't be patented, as long as you don't use art assets and audio taken from the original game, you'll be within your rights. This is the approach other educational/preservational game clones take. See openXCOM and Reconstructing Cave Story for more info. But since it's such a new game I'm not sure if the devs would be pleased or angry. I'd change your goal to make something SIMILAR but not the same as HLD.

It's a cool idea and I love the personal challenge aspect of it. Hope your family matters are okay.
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #15 on: November 07, 2018, 05:00:00 AM »

Here I am. I'm not dead:D
Video with short explanation of what's going on:




Godot

Finally, I started using Godot Engine. I was interested by its node system. You just create scenes, put them into another scene and at the end of this process you'll have a complex object with clear hierarchy. That’s how I thought:D In reality it isn’t that easy … for me… for now. I have some difficulties with Godot, like adding spritesheets and making objects communicate to each other. But I want to dive deeper, cause I don’t feel, that I clearly figured out what Godot is, what its advantages are and what engine I want to work with.

GitHub

Now I have repositories on GitHub, so you can see all the code or use it if you want. There are both versions of HLD on GitHub.

Godot version: https://github.com/oKatanaaa/HLD-Godot
GameMaker version: https://github.com/oKatanaaa/HLD-GameMaker

I decided not to write code reviews here, the reason is time, I wanna focus on coding and other stuff. If you have any question(or just wanna say something:D), just mail me or write here, I’ll try my best to answer anything you ask.

P.S. Video will be released as soon as possible Wink
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #16 on: November 07, 2018, 07:58:53 AM »

Now it's time for stupid ideas, I DONT CARE. I started creating player object in Java in hope that it will be easier that in GDScript. Well, it isn't, but while writing this class I come up with idea how to organize finite state machines in Godot.
Here is mockup:

Code:
enum State { MOVE, JUMP, ATTACK }
var state
var spriteDir
var moveDir
var attackDir
var jumpDir

fun process(){
set_sprite_dir()
set_move_dir()
set_attack_dir()
set_jump_dir()
play_state_logic()
}

fun play_state_logic() {
match state {
case MOVE:
move_logic()
case JUMP:
jump_logic()
case ATTACK:
attack_logic()
}

Each function described above does something is related to function's name. Changing state will be in state_logic functions. But there are several bad things. Those "set" functions set related to them variables every frame per second and it's bad because some of the states need only last data since previous state. Need to modify this architecture.
Logged

Mr.Kitty
Level 0
**


View Profile
« Reply #17 on: November 18, 2018, 09:23:35 AM »

Currently I have no idea what to write about:D, so here is some little news about development progress:
  • New architecture for the player object(drifter)
I tried out an architecture I described in the last post. It works and allows me to add states "beautifully". I'm not sure how it will get on in the future, when the object will have much more complex states, but it suits for me for now.
Of course, I modified this idea. Now changing of the main properties(moveDirection, spriteDirection and etc) can be turned off in the state logic function(property changing depends on current state).
  • I started making first Hyper Light Drifter level
I was wondered how HLD creators made this lighting in the game. Well, they just have added a new layer with predrawed shadows to the room! But it is not enough just to add a layer with a shadows, actually, if you want to reach the same look like in HLD.


Currently it looks like this:





Game equivalent:



Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic