Fractal Block World
Version 1.01.27
Back
There is now a GUI in the program for selecting
which mods to use.
Perlin noise has been added to world generation.
Updates
Version 1.01.30:
- Date: Not released yet
- A new dungeon has been added:
Supermassive Black Holes.
These are at the center of Galaxies.
In the treasure room you can pick up the following new
Dark Hole weapon mode: The Quasar Drive.
This is like the Dark Hole drive, except it costs 60 dark holes to use
(instead of 20) and it makes the player move even faster.
It still lasts only 30 seconds, but you can "stack it"
up to 300 seconds.
- When Lua code calls a C++ game API function,
the C++ will check that 1) the number of arguments is correct,
2) no argument is nil, and
3) every argument is of the correct type.
Now, this kind of check can also take place for
block scripts calling Chunk Generation API functions.
This is enabled by setting the variable
engine.lua.chunk_gen_check_args
to true,
but it is false by default.
We recommend this check for a modder to safely catch errors
in their chunk generation code.
However, end users should leave this variable false
for speed reasons.
- Now when the engine respawns the player,
the engine will (if the package wants)
call a Lua function to make sure
the respawn chunk is safe.
This is important because in a package where blocks
can be created and destroyed, the respawn chunk might
become invalid and hence the package would need to
figure out how to safely respawn the player.
- Now moving entities have a variable called __hide.
When this is true, then
1) they are not rendered,
2) their hard coded engine update is not processed,
3) you and other moving entities cannot collide with them,
4) they do not process "alarms", and
5) they do not show up in moving entity range queries.
However their Lua __on_update function is called,
which is one way you can use to unhide them again.
- Recall that there is a "system hud" and the
"package hud".
You can now hide any part of the system hud,
or even hide the entire system hud.
See the variable
display.hud.hide_system_hud
.
The user can use that variable to hide the system hud.
However, if the package wants to hide the system hud,
this should be accomplished with the variable
game.window.hud.hide_system_hud
.
- The environment variables associated to
the crosshair have changed.
See the variables that start with
display.hud.crosshair
.
- Now every music playlist can have a file called "import.txt".
Every line of this file should be the name of a playlist.
The local files in those playlists listed in the import.txt file will be
added to the current playlist (the playlist which contains the
import.txt file).
- Now the rail of any railgun weapon can hit a monster at most once.
Before, if you were small enough, a rail would pierce an enemy and do damage
across several frames.
Rails are still piercing.
- Monster health is no longer hardcoded into the engine.
Instead, you can register that a Lua function gets called whenever a specified
moving entity variable changes.
Related to this, moving entities no longer have
__on_die
functions.
The concept of a moving entity dying because its health reaches zero
is now completely soft coded as part of the xar package.
- Now as a modder, you can choose to not pause the game if there is a window
on either the game stack or main menu stack.
The way you do this is by calling
ga_set_game_paused_while_on_win_stack
.
- Now
you can pass global variables to Lua worldgen code.
These are only updated when you reload the package.
It is intended that these are set when a new game is created
and then are never modified afterward.
Let us give an example of how this works.
In the
globals.txt
file of your package, add the line
"b worldgen.state.lots_of_rockets true
" (without quotes).
This adds a certain boolean variable.
The variables that worldgen has access to must all start with
"worldgen.state.
".
To be clear, this variable in the engine's variable environment is
game.globals.worldgen.state.lots_of_rockets
.
Then, in a chunk generation script __main
function,
you can call state_get_b("lots_of_rockets")
to get the value
of this bool.
- Now if there is a problem placing the player when a new game is
created, they will be forced to reboot the game.
Such a problem can occur if the user forcibly exists the program
while the game is placing the player in the world.
- Named pipes are in beta.
A named pipe allows the Fractal Block World program to communicate
to other programs on your computer.
Once you give Fractal Block World permission,
it can create a named pipe on your computer
(which it can read from and write to).
Then, other programs on your computer can
read from or write to that same named pipe.
It is up to you to run those other programs:
Fractal Block World will never
launch a program on your computer.
Use this feature at your own risk.
The concern is you should never download untrusted
programs onto your computer and run them.
Fractal Block World is not liable for anything detrimental
that happens by you downloading software
from the internet (or any other source) and running it.
Note that Fractal Block World is also not liable
for anything bad that happens as a result of using the
Fractal Block World game.
- In a previous update we made the input binds system
clear keys as soon as it is updated but it missed the previous update.
Now, we are changing the behavior slightly.
Once the input binds system misses an update,
it will immediately clear keys.
Clearing keys means simulating a key up event for each
key that the input binds system thinks is down.
- We fixed an old quirk of the engine:
monsters only respawning when the chunk they are in
is recreated.
Now, part of a chunk's update cycle is to see if any moving
entities (created originally from procedural world generation)
need to be respawned.
This fixes the glitch where users were able to remove
the Inner Core at the end of the game by sleeping
for an hour in a certain location.
- There is a new mini area: The Space Root Pink Prison.
If you try to use Pink Rings in Outer Space, this area will
trap you to prevent you from growing out of the Space Root chunk.
Although there was no way to abuse this previously,
it is probably safer to have it this new way.
Players may find this area interesting for other reasons as well.
Version 1.01.29
- Date: August 2025
- Now there is optional mesh directional lighting.
You can enable this with Options -> Engine -> Rendering.
You can change the min and max lighting values.
Also note that in the same place you can easily turn on anisotropic filtering
(before you needed to do this from the console or program_startup.txt).
- Prior to this update, chuck files would be removed as soon
as possible.
With this update, we wait until the user saves the game before we remove
any chunk files.
This way as long as the player is using the new database model
(db2, the SQLite database), we can bundle the remove chunk file queries
into one "database transaction".
This will make it faster
and possibly reduce lag spikes while playing.
- Now when the user loads a game, we see if the "manifest file"
and the chunk file database are out of sync.
(The manifest is a list of basic information about every chunk file
in the database).
If they are out of sync, the system deletes the manifest file
and automatically recreates it.
As a result of this and the previous bullet,
the first time you load a game that was played in
1.01.28 and then save it, it may take a few seconds to delete
any chuck files that are no longer being used.
This is normal.
- The db2 (SQLite database for chuck files)
is now defragged periodically.
Specifically, we defrag it if you have played a game
more than an hour or if you have saved 100 times
(whichever comes first).
On the developer's machine, defragging takes only a fraction
of a second.
- Prior to this update the game used a mixture of
4 byte and 8 byte floats for environment variables
(and global variables).
Now, all floats are 8 byte
and their type is all referred to by the letter
f
.
So, the letter d
is no longer used to
refer to 8 byte floats
(we use f
for all floats across the entire engine).
This will simplify life for modders.
- We now use a different algorithm for "clearing keys".
A typical problem to solve is the following:
you press the brake key, open a menu, release the brake key,
then close the menu.
We do not want the brake to be on anymore.
The new algorithm works as follows:
The key binding system has a list of which keys it thinks are down
(which may not actually be the keys which are down).
When the key binding system misses an update,
it clears all keys which it thinks are down.
Also, a key up event has no effect if the keybinding system
does not think that key is down.
- In a previous update we made it so you cannot telefrag any monster
by either 1) growing or 2) saving + loading.
This was because we didn't want people cheesing the final boss
(the Inner Core).
However, we are now relaxing this rule.
Now you are allowed to telefrag any monster (in the xar package)
other than the Inner Core.
- The secondary homing weapon has been nerfed.
One problem was it did way too much damage, so that has been reduced.
Also, now a monster can only be hit 5 times with a homing rocket before
that monster has a 4 second cooldown.
So, the homing weapon is still good against a large number of weak monsters,
but it is no longer good against a single enemy with lots of health.
Version 1.01.28:
- Date: July 2025
- There is now an optional cursor for menus.
You can specify whether there is a cursor for both
windowed mode and fullscreen mode.
The intended use case is to not use a cursor
for fullscreen mode, but then the user can quickly
ALT-ENTER to windowed mode and use the cursor to
click outside of the window.
- The game now uses a database for saved games.
You can read more about that here.
This should help Linux users.
Which database type being used is specified by the variable
engine.chunk_db.type
.
This should be set to "db2" (without the quotes).
When you create a new game, it will use the specified database type.
The database type db1 has one file on disc per modified chunk
(resulting in potentially thousands of files) which can be slow on Linux.
The db2 type uses a SQLite database (one file on disc).
Note that the variable engine.chunk_db.type
only specifies
what type of database is used for new players that are created.
It does not change old saved games.
You can tell if db1 is being used because it will show a yellow cylinder
icon on your HUD with the number 1 on it.
On the other hand, if you are using db2, it will not show an icon.
- Chunk files in the new database type are
compressed
using the zlib library.
- In Tweedle-Dee Air (or is it Tweedle-Dum Air?)
there is a Tweedle Haunted House.
These has several dungeons all focused around the idea
of it being dark and you need to worry about seeing.
- In addition to the old waypoint system,
there is a new related system: bookmarks.
Many waypoints in the world are now next to "bookmarks"
(when it is not confusing).
When you right click on a bookmark, it will become your
"current bookmark", and you will be teleported to your
current respawn point.
This is intended to "quickly go back to town to buy and sell".
Then, when you right click on ANY respawn point,
you will be teleported back to your current bookmark.
This will be an easy system which handles
a common case of traveling.
Before this, you would use "temporary waypoints",
but that required more UI navigation.
- There is a new weapon mode for your Dark Hole weapon
called the Black Hole Drive.
This decreases air drag for 30 seconds, allowing you to move
at about twice the speed.
This can be found at the end of the Catacombs.
- You can improve your telekinesis
ability at certain stations.
You can increase your telekinesis radius.
The starting radius is 24.
Also, if you have not used telekinesis for 30 seconds,
your next telekinesis is free
(does not cost money).
This number 30 is decreased when you upgrade your
telekinesis ability.
- There is now a town at the top of I3 Inner Trees
called Starksboro.
Inside this town is the Library Library,
which tells you where the libraries are in the world.
Also in Starksboro is a Green Key.
Can you figure out where to use it?
- There is now a library in the treasure rooms
of Amethysts: the Pink Library.
This tells you which areas have Pink Rings which allow you to
teleport outside of those areas.
- Several API functions have been deprecated
(or removed entirely) and replaced by
better solutions.
This includes the genesis mode bool, pink ring teleportation,
and blue ring teleportation.
See here
for a list of such changes.
- You now create a mod to change the
font that the game uses.
You can use either a texture atlas or a collection of images
for each individual character (or a combination of the
two methods).
See the guide in the guide list
here about fonts.
- If you are modding, you can create you own
Pink Ring
type entities.
See the guide in the guide list on Pink Rings.
- If you are modding, you can create your own
Blue Ring
type entities.
See the guide list.
The tricky part about this kind of teleportation
is that the engine needs to generate the chunk tree
and the Lua code needs to guide how this generation should take place
(the Lua needs to specify where to shrink the player).
The key technical addition to the Game API is the
explore while loop.
- If you are modding, you can create your own
Waypoint like entities.
That is, you can teleport from chunk A to chunk B,
and then back again if there is a problem.
See the guide in the guide list for teleportation.
Part of that guide includes the
Teleportation Manifesto, which explains the
thought process behind this kind of teleportation.
This teleportation is significantly different from
Blue Ring teleportation, because here we know the
block path of chunk B ahead of time, and the engine
does the heavy lifting to move the player to that chunk.
- If you open the console and run the command
gendoc
,
then in addition to what it did before,
it will create the folder
Output/Documentation/ProgrammingAPI
and it will generate several useful files there.
These files list the functions you can call from Lua,
and the Lua functions which are called by the engine.
The latter functions all start with a double underscore.
You might want to have some of these files open while
you read the Creation Manual.
- You can now call Lua code from the console.
That is, you can call functions defined in Lua scripts
in the game directory of your current package.
Open the console and type the command
execl test_console_to_lua.foo HELLO_WORLD
.
This will go to the file
test_console_to_lua.lua
and run the function called foo
.
It will pass it HELLO_WORLD
as a (string) argument.
The string argument is optional.
The foo function is allowed to return back a string.
In the test_console_to_lua.lua
file, the function
foo
should be defined in the usual way that
module functions are defined:
function p.foo(arg) ... end
.
The command execl
will look for scripts in the
Game/
directory of the current package and the
Input/Scripts
directory.
This way the user can use their own Lua scripts for keybindings.
- Previously if there is no music in a playlist folder
in a mod, the system will use the parent folder
as a playlist.
This can cause a problem with Windows if the path names
are too long.
So as an option, we did the following:
a playlist folder F can have a file called parent.txt
which contains the name of the playlist which is to be
played if the playlist F has no music in it.
- When blocks are rendered, we shade
each 1x1 square differently depending on
the direction it is facing.
Now, we can specify these colors
in the function "top.__get_level_color".
This function takes as arguments the level
of the chunk being rendered as well as the
block direction.
This is called accordingly at the beginning
of each render cycle.
See how the xar package defines this Lua function.
Now the xar package does something new:
once the player's level is more than 500,
blocks will start to become darker.
This will continue until reaching level 2000,
at which point blocks are completely black.
Another interesting thing you could do is
color levels based on their difference
to the viewer's level.
We encourage people to have fun
modding this function.
- Blocks can now have their own custom render functions.
See package_tutorial2 for how to do this.
If a block script has an __on_render function,
that will be used to render the block.
However in this case the block must not be
"visibly solid".
- You can now render (textured) 3D triangles from Lua.
You do this with the function
ga_render_triangle
.
You specify the vertex positions and uv coordinates
of each vertex.
By calling the function ga_render_color
before rendering such a triangle, you can shade
it whatever color you want.
- Previously the game could render 6 levels of detail.
Now it can render up to 50.
You can specify the number of levels to render by
putting a line like the following into your
Input/Scripts/program_startup.txt
file:
set engine.render.num_render_levels 10
.
If you do this, you might also want to open the console
while you are playing the xar package and enter the following
command:
set package.state.globals.render.levels_fade_out_local.enabled true.
This will cause levels to be shaded darker if they are far away
from the player's current level.
For example, since in this configuration we are describing we
render 10 levels of detail, the player's level L will be
100% bright, the next coarsest level L-1 will be 90% bright,
the next coarsest level L-2 will be 80% bright, etc.
You can also set
package.state.globals.render.levels_fade_out_local.max_level_shade
and
package.state.globals.render.levels_fade_out_local.min_level_shade
to tweak the behavior (setting the shade value of the
viewer's level (max render level) and the min render level.
This is a reasonable configuration:
You cannot set the fertile_radius beyond level "9":
It defaults to a radius of 1.
- Improve the efficiently of some "pointer" code.
Version 1.01.27:
- Date: April 2025
- There is now a GUI (in game) for the player to select
which mods to use.
Mods should be installed in either Data/Packages or Input/Packages
(depending on the mod).
The mod selection GUI allows the player to select mods
and choose the order in which they are applied.
This order must agree with the dependency requirements
of the relevant mods.
- Added new area: the White Rose.
This has some health upgrades and 600% armor.
- Added a White Rose to a secret area in
the Mylantis Caves Library.
Can you find it?
- Added new area: I3 Clouds.
You can use these clouds to refuel on ammo.
There are also White Roses in them.
These clouds use Perlin Noise, which is the first
time FBW is using this.
All previous caves were "stick and ball caves".
- There is a new weapon mode for the laser:
the Freeze Ray.
This costs 2 ammo and freezes for double
the usual amount of time.
However the freeze time is "stacking".
This can be found at the end of the treasure room
in the Deep Sliver Maze.
- Added new area: the Deep Sliver Maze.
This can be found on the pyramids in Rivers in I3.
However you must be
inside of a Rainbow Flower
inside a Sagittarius Portal
inside a Rainbow Flower
inside a Sagittarius Portal.
- Converted the secret trophy for the Mahogany Treetop
into a regular trophy.
Also, added lore there.
- Created a trophy for the Mahogany Inner Tree
and added lore there.
- Added lore to the treasure room of a Clay Planet.
- You will have to download the new version of the xar chunk edit package
for it to work with this version of the game.
- Now when you kill monster projectiles in Pacifist mode,
it does not increase your kill count.
- When you are in a text box, if you do LCTRL + C,
it will copy the text of the textbox to your computer's clipboard.
- It is now much easier for a modder to add their own
weapon to xar.
You add a new Lua script for the weapon to Data/Packages/xar/Game/Item.
See the files Data/Packages/xar/game_inv_exec.lua
and Data/Packages/xar/Item/item_gun_1_1.lua
for documentation.
There are now 20 strings which specify which weapons
are equipped.
If the modder adds a weapon called
Data/Packages/xar/Game/Item/foo_weapon.lua for example,
then if they somehow set the global variable
xar.player.equipped.1.primary to "foo_weapon",
then when the player selects weapon 1 and uses the primary fire,
it will shoot the foo_weapon.
- Added better protection against the player
leaving the tutorial without fixing their
game difficulty.
Put a glass wall in front of the debug room
of Rainbow Flowers so now it can only be reached
by cheating.
- You can now sort waypoints by "last used time".
Also, the menu shows basic information about the
currently selected waypoints: its level,
how long since it has been used,
and how long since it was first enabled.
- Moved the location of the menus to
copy and delete players.
These are now in Options -> Game Loading/Saving.
- Fixed the bug with Progressive Rockets where
they would pierce instead of being removed.
- One way blocks can now be added via Lua block scripts.
See the package_tutorial2 for how to do this.
- You can now provide a custom __on_render function
for a moving entity.
See Data/Packages/xar/MovingEnts/Other/ment_marker_short.lua
for an example of this.
Previously short and long markers were being rendered by the engine
using special C++ code (because they "blink"), but now this is done with Lua code.
- There are now API functions for getting the object
that the player is looking at.
See for example ga_look_object_block_get_chunk_id.
- There are now API functions for drawing lines in the world.
These can be used inside "__render_augmented" functions.
This, together with the API to get the block the player is looking at,
makes it easy for a modder to draw a wireframe cube showing
what block the player is looking at.
- Previously there was a bug which could be done as follows:
open the console and enter the commands "save", "load", "save", "load"
(in 4 different lines).
This would result in teleporting the player to the center of the chunk
that they were in.
This could be used to bypass doors.
It is now no longer possible to do this bug,
although you can enable it for cheating with the variable
"engine.cheat.enable_player_slsl_bug".
- In a previous update we introduced the "telefrag probation period".
This is an interval of time in which the player is not allowed to
telefrag anything.
Now, when the player loads a game, they are immediately placed
in a telefrag probation period.
This prevents the player from telefragging a monster by opening the
console and entering the commands "save", "load", "save", "load".
If the player tries to telefrag in their
telefrag probation period, they will be teleported to their
"last safe position", unless that cannot be found,
in which case they will be respawned.
- We made a breakthrough: the program is able to track
the exact amount of memory it has allocated.
However for performance reasons, to enable this counter
you must add the following line to Input/Scripts/program_startup.txt:
"set engine.memory.enable_memory_counter true".
With this enabled, when you go into the main menu
in the upper left corner it will show you how much memory
has been allocated.
This will be a fraction of what the task manager says
the program is using for memory.
- Now using the new memory counter,
we were able to figure out how to decrease the memory footprint
of the program.
Also, the vast majority of "pointers" have been converted to
shared pointers (C++ std::shared_ptr).