Compare commits
No commits in common. "f5598d3ea2346a5cc01891921e1f1107d0cfb44f" and "7c8f817310663baf6c96d7137582d2025eee6f6e" have entirely different histories.
f5598d3ea2
...
7c8f817310
6 changed files with 147 additions and 22 deletions
|
@ -3,9 +3,9 @@
|
|||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: localhost
|
||||
-- Generation Time: Jul 20, 2024 at 02:33 PM
|
||||
-- Server version: 11.4.2-MariaDB
|
||||
-- PHP Version: 8.3.9
|
||||
-- Generation Time: May 12, 2024 at 03:59 PM
|
||||
-- Server version: 11.3.2-MariaDB
|
||||
-- PHP Version: 8.3.6
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
START TRANSACTION;
|
||||
|
@ -20,6 +20,8 @@ SET time_zone = "+00:00";
|
|||
--
|
||||
-- Database: `zdenekborovec`
|
||||
--
|
||||
CREATE DATABASE IF NOT EXISTS `zdenekborovec` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
USE `zdenekborovec`;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
@ -27,15 +29,13 @@ SET time_zone = "+00:00";
|
|||
-- Table structure for table `blogposts`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blogposts` (
|
||||
CREATE TABLE `blogposts` (
|
||||
`blogpost_id` uuid NOT NULL DEFAULT uuid() COMMENT 'uuid of the blogpost',
|
||||
`readable_address` varchar(64) DEFAULT NULL COMMENT 'Human-readable addressing alternative for an article. For example, blogpost with readable_address = "example" can be accessed by article.php?address=example.',
|
||||
`title` varchar(64) DEFAULT NULL COMMENT 'title of the blogpost',
|
||||
`abstract` varchar(512) DEFAULT NULL COMMENT 'short version of the blogpost to be displayed as preview, usually the first paragraph of the real article.',
|
||||
`content` text DEFAULT NULL COMMENT 'html for the article',
|
||||
`date_posted` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Datetime at which the article was posted.',
|
||||
`date_edited` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at the lasted edit.',
|
||||
PRIMARY KEY (`blogpost_id`)
|
||||
`date_edited` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at the lasted edit.'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -44,14 +44,13 @@ CREATE TABLE IF NOT EXISTS `blogposts` (
|
|||
-- Table structure for table `blogpost_comments`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blogpost_comments` (
|
||||
CREATE TABLE `blogpost_comments` (
|
||||
`comment_id` uuid NOT NULL DEFAULT uuid() COMMENT 'ID of the comment, PK.',
|
||||
`parent_id` uuid DEFAULT NULL COMMENT 'If this is a response to a comment, this is the id of that parent comment.',
|
||||
`blogpost_id` uuid NOT NULL COMMENT 'ID of the blogpost this comment is under.',
|
||||
`poster_id` uuid DEFAULT NULL COMMENT ' ID of the user who posted this comment. ',
|
||||
`timestamp` timestamp NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp when the comment was posted.',
|
||||
`content` mediumtext NOT NULL COMMENT 'Content of the comment. Stored as markdown.',
|
||||
PRIMARY KEY (`comment_id`)
|
||||
`content` mediumtext NOT NULL COMMENT 'Content of the comment. Stored as markdown.'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Comments on blogposts.';
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -60,11 +59,9 @@ CREATE TABLE IF NOT EXISTS `blogpost_comments` (
|
|||
-- Table structure for table `blogpost_has_tag`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blogpost_has_tag` (
|
||||
CREATE TABLE `blogpost_has_tag` (
|
||||
`blogpost_id` uuid NOT NULL,
|
||||
`tag_id` int(11) NOT NULL,
|
||||
KEY `blogpost_id` (`blogpost_id`),
|
||||
KEY `tag_id` (`tag_id`)
|
||||
`tag_id` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -73,11 +70,10 @@ CREATE TABLE IF NOT EXISTS `blogpost_has_tag` (
|
|||
-- Table structure for table `blogpost_tags`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `blogpost_tags` (
|
||||
`tag_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID of the tag, primary key.',
|
||||
CREATE TABLE `blogpost_tags` (
|
||||
`tag_id` int(11) NOT NULL COMMENT 'ID of the tag, primary key.',
|
||||
`name` varchar(32) NOT NULL COMMENT 'Name of the tag, will be displayed.',
|
||||
`color` varchar(32) NOT NULL COMMENT 'CSS color string, will be displayed.',
|
||||
PRIMARY KEY (`tag_id`)
|
||||
`color` varchar(32) NOT NULL COMMENT 'CSS color string, will be displayed.'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Tags that can be used to tag and filter blogposts.';
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -86,16 +82,60 @@ CREATE TABLE IF NOT EXISTS `blogpost_tags` (
|
|||
-- Table structure for table `users`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `users` (
|
||||
CREATE TABLE `users` (
|
||||
`user_id` uuid NOT NULL DEFAULT uuid() COMMENT 'UUID of the user. Primary key.',
|
||||
`username` varchar(64) NOT NULL COMMENT 'Display name of the user.',
|
||||
`password` varchar(255) NOT NULL COMMENT 'password encrypted by password_hash().',
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp() COMMENT 'Timestamp at account creation.',
|
||||
`permissions` bit(8) NOT NULL DEFAULT b'0' COMMENT 'Permission mask for the user. Rules (from left to right):\r\n0: Can post blogposts.\r\n1: reserved\r\n2: reserved\r\n3: reserved\r\n4: reserved\r\n5: reserved\r\n6: reserved\r\n7: reserved',
|
||||
PRIMARY KEY (`user_id`),
|
||||
UNIQUE KEY `username` (`username`)
|
||||
`permissions` bit(8) NOT NULL DEFAULT b'0' COMMENT 'Permission mask for the user. Rules (from left to right):\r\n0: Can post blogposts.\r\n1: reserved\r\n2: reserved\r\n3: reserved\r\n4: reserved\r\n5: reserved\r\n6: reserved\r\n7: reserved'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
--
|
||||
-- Indexes for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- Indexes for table `blogposts`
|
||||
--
|
||||
ALTER TABLE `blogposts`
|
||||
ADD PRIMARY KEY (`blogpost_id`);
|
||||
|
||||
--
|
||||
-- Indexes for table `blogpost_comments`
|
||||
--
|
||||
ALTER TABLE `blogpost_comments`
|
||||
ADD PRIMARY KEY (`comment_id`);
|
||||
|
||||
--
|
||||
-- Indexes for table `blogpost_has_tag`
|
||||
--
|
||||
ALTER TABLE `blogpost_has_tag`
|
||||
ADD KEY `blogpost_id` (`blogpost_id`),
|
||||
ADD KEY `tag_id` (`tag_id`);
|
||||
|
||||
--
|
||||
-- Indexes for table `blogpost_tags`
|
||||
--
|
||||
ALTER TABLE `blogpost_tags`
|
||||
ADD PRIMARY KEY (`tag_id`);
|
||||
|
||||
--
|
||||
-- Indexes for table `users`
|
||||
--
|
||||
ALTER TABLE `users`
|
||||
ADD PRIMARY KEY (`user_id`),
|
||||
ADD UNIQUE KEY `username` (`username`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for dumped tables
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for table `blogpost_tags`
|
||||
--
|
||||
ALTER TABLE `blogpost_tags`
|
||||
MODIFY `tag_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID of the tag, primary key.';
|
||||
|
||||
--
|
||||
-- Constraints for dumped tables
|
||||
--
|
||||
|
|
BIN
docs/www/blog/godot_spell_system_prototype/console.png
Normal file
BIN
docs/www/blog/godot_spell_system_prototype/console.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7 KiB |
BIN
docs/www/blog/godot_spell_system_prototype/grass.png
Normal file
BIN
docs/www/blog/godot_spell_system_prototype/grass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
85
docs/www/blog/godot_spell_system_prototype/index.php
Normal file
85
docs/www/blog/godot_spell_system_prototype/index.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
|
||||
<?php
|
||||
$PageTitle="Zdenek: Blog";
|
||||
|
||||
$COMMONS = $_SERVER['DOCUMENT_ROOT'] . "/../common";
|
||||
|
||||
include_once($COMMONS."/header.php");
|
||||
?>
|
||||
|
||||
<article>
|
||||
<h2>
|
||||
Godot spell casting system prototype.
|
||||
</h2>
|
||||
<div class="blog-metadata">
|
||||
<span class="blog-tag" style="background-color: cornflowerblue">
|
||||
godot
|
||||
</span>
|
||||
<span class="blog-tag" style="background-color: khaki">
|
||||
game-dev
|
||||
</span>
|
||||
<span class="blog-tag" style="background-color: sienna">
|
||||
the-labyrinth-II
|
||||
</span>
|
||||
<span class="blog-publish-date">
|
||||
Published on: 2024-01-13
|
||||
</span>
|
||||
</div>
|
||||
<p>
|
||||
I wanted to implement this system in my game "The Labyrinth II" ever since I was maybe 13, but the project failed a few times and for the last few years it has been just rotting in the back of my mind. Well, I have decided to return to it again.
|
||||
</p>
|
||||
<p>
|
||||
The system is inspired by the spell casting system in the videogame <a href="https://en.wikipedia.org/wiki/Dungeon_Master_(video_game)">Dungeon Master</a>. I really liked the way you had to actually study the spells and then cast them. This was not selecting a option in a menu, it was way more involved - and exciting. Originally, when I was thinking about the spell system I wanted in my game I just wanted to pretty much copy their system, but at some point, this appeared to me as a better idea. I think it will allow you to feel not like you are uttering the spells, but insted like you are casting them with your wand, or finger, or a screwdiver or whatever. Plus it gives you a nice natural way to upgrade it once you do get a better mana-channeler: just increase the dimension of the matrix! Allows you to cast new, more complicated spells, and does so in a natural way only once you've mastered the simpler spell matrix.
|
||||
</p>
|
||||
<p>
|
||||
Now, I have to admit, that I am not at all sure if this system will actually work in a modern game, or, really any game that's not basically turn-based. I do have some ideas how to solve these problems (including a time slow-down mechanic), but that is too far in the future now. I am planning on taking this very easy and slow, more focused on having fun and exploring the godot engine, rather than trying to sprint to the goal of a finished game.
|
||||
</p>
|
||||
|
||||
<div class="image-gallery">
|
||||
<h2> Gallery </h2>
|
||||
<div>
|
||||
<div>
|
||||
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/nodes.png" alt="A screenshot of the spell casting system.">
|
||||
<p>
|
||||
A path drawn between some nodes, this is what the spell casting looks like.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/console.png" alt="A screenshot showing cast spells log.">
|
||||
<p>
|
||||
A log from the spellbook, it detects all entered paths. It also has a dictionary of paths and spells, if you enter a path that corresponds to a spell, you cast it!
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<img src="http://www.zdenekborovec-dev.cz/blog/godot_spell_system_prototype/spellbookexports.png" alt="A screenshot from the godot editor showing node export values.">
|
||||
<p>
|
||||
This is how I can interact with the spellbook from the editor. I can add in nodes (it then works with them automagically, so I am not anyhow limited to the 3x3 grid). And I can also add in the spell paths and names (I can then use these to emit a spell_cast event with its name, or something like that).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Once I tried actually using it in a control node, I found out the mapping of the mouse was completely off, I remade it into control nodes, which I am actually happy about as I feel like the nodes being buttons makes more sense than them being sprites with a collision box that only reacts to the mouse, or whatever I was using, I don't wven remember, but it was wacky :D. But I encountered a problem! I still had to use the Line2D, which is a Node2D. And it's position just did not map well. Through experimentation I found out that it was using the position as relating to its scene origin, but once the control scene was inserted into a control container, it got scaled, as controls should, but it was now offset and the line was not. The only solution I could find was putting the SpellBook scene inside of a MarginContainer, and offseting it using margins and thus preserving its 'relative origin', instead of letting it stretch. I do not like this solution as it requires manual fiddling if you want to change up the HUD, but it was the only solution I could find.
|
||||
</p>
|
||||
<p>
|
||||
Here is a bit of code, so that I can test my code block css:
|
||||
</p>
|
||||
<code>
|
||||
## Add a node to current spell
|
||||
func _on_spellnode_entered(node: SpellNode)->void:
|
||||
if is_receiving_spell && not spell_builder.has(node):
|
||||
# Append node to the spell builder
|
||||
spell_builder.append(node);
|
||||
# Add new point to the spell line and set the old top to the new nodes position
|
||||
spell_line.add_point(node.position)
|
||||
spell_line.set_point_position(spell_line.get_point_count() - 2, node.position)
|
||||
</code>
|
||||
<p>
|
||||
I would like to add some kind of syntax highlighting, but from my research I'd have to write a php function for that, as css cannot look for key words, and writing a bunch of php is not something I am currently in the mood for, so this will have to do, for now.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<?php
|
||||
include_once($COMMONS."/footer.php");
|
||||
?>
|
BIN
docs/www/blog/godot_spell_system_prototype/nodes.png
Normal file
BIN
docs/www/blog/godot_spell_system_prototype/nodes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
docs/www/blog/godot_spell_system_prototype/spellbookexports.png
Normal file
BIN
docs/www/blog/godot_spell_system_prototype/spellbookexports.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Loading…
Reference in a new issue