jorgegv / rage1 Goto Github PK
View Code? Open in Web Editor NEWRAGE1: Retro Adventure Game Engine, release 1
License: Other
RAGE1: Retro Adventure Game Engine, release 1
License: Other
It would be useful to have a flowgen action to interact with elements screens different than the current one.
An easy way to pass 1 bit of information from one screen to another would be the following:
Branch: screen_state
With the above changes, the possible chain of events in the game would be:
Write a detailed step-by-step tutorial based on my own development of Famargon.
Share it in z88dk and spectrumcomputing forums
Contents:
In the 1K BSS mentioned in issue #46, 768 bytes correspond to the tile type array which is used to check if a char position on screen is an OBSTACLE, a DECORATION or an ITEM (or something else in the future).
Reducing this array is difficult, because it is accessed very often from several points multiple times, and the speed of calculating the index into the array and returning the item type is critical.
A small test has been tried by packing 4 cells per byte (allowing for 4 tile types - we are using already 3...), but the complexity of calculating the index for returning the tile type made the code larger and it ate most of the memory reduction which was obtained by the packing (from 768 bytes to 192 bytes).
Speed seemed not to be affected very much, though... Some more tests are needed and perhaps this is a good way to scratch a few hundred bytes.
Algorithm ( A = Tile number 0-767; T = Type 0-3 ):
GET(A):
SET(A,T):
Update 1:
btile_get_tile_type
function. Supposedly we were going to gain 576 bytes minus the get/set functions (126 bytes) and minus the calling overhead.btile_get_tile_type
. So with this, the game loop isslower (the sprites move way slower), and also, since we have 21 times the function is called, the parameter marshaling overhead eats up almost all memory savings. So with this test, we get a slower game, and just for a gain of ~130 bytes.Update 2:
Allow for some way to specify a background for a screen in the map. E.g. tiles, background and ink colors, etc.
Allow for animated btiles.
Tasks:
enemy.c
)btile_animate_all
function, which animates only animated btiles, extracted from the table indicated in the previous stepNotes:
Add multiple CHECK and DO sections in flowgen rules. The flowgen tool already parses this, but it only used the first CHECK and DO action to generate the code (as of now)
It must generate code for all the checks and actions, and the engine must be adapted to run all of them.
Several CHECKs in the same rule is the way to specify AND conditions. Several rules is the way to specify OR conditions.
CHECKs must be evaluated in shortcircuit mode. ACTIONS must be executed in order.
When this code is in place, the specific checks for game ending related to the demo game can be completely removed from the main game loop in the engine source, and thus it will be completely generic.
Document DATAGEN file format in detail
Refactor Hero animation code to use the animation sequences implemented in #37
The BSS data segment takes now around 1K and it's mainly composed of static local variables (i.e. local variables defined as "static" inside functions). This was done supposedly for speed reasons: variables with fixed addresses are much faster to handle than (IX+offset) based ones.
Maybe we don't need to optimize for speed in those cases, and those variables can be just declared as local (stack) variables. If this is the case, we woud gain an additional 1K for game code. Stack usage will increase, since local variables that were fixed in memory will now be allocated on the stack.
Tasks:
Tasks:
It is interesting to have an enemy movement type that allows to have different animation sequences depending on the direction it is moving. When the multiple animation sequence feature is implemented (#37) this issue is really easy to implement.
Most probably the animations for one direction would be mirrored images from the other one, but this is not required, both can be specified separately.
Animation sequence can change when bouncing horizontally or vertically.
Fire: add animation to bullets
Refactoring bullet animation code with the regular sprite animation code (with animation sequences implemented in #37 ) should make this very easy
Notes:
screen_dataset_map
table in dataset.h
. It should be used in enter_screen for selecting the proper dataset.all_items
, all_sprites
, all_btiles
. etc.)map.c
functions that walk all screens for resetting enemies/sprites: Fix bug #51game_config
setting zx_target
, with 48/128
possible values. If not specified, default to 48
.zx_target
is 48
, ignore datasets and output all assets in the home
datasetscreen_dataset_map
tableWhen we have small sprites (e.g. bullet, which is 5x5 pixels in the demo game), we can optimize the sprite drawing by specifying hthresh and vthresh for the sprite, which indicate what minimum rotation values are needed to draw the external (right and bottom) cells (with small sprites, or sprites that do not fully fill their bounding boxes, these cells may not be needed).
By default hthresh and vthresh are 1, but they can be set to the following for better optimization:
This optimization can be applied to all sprites, not just small ones. Since the defaults are 1, DATAGEN should not generate code for changing it if the calculated values for XTHRESH and YTHRESH happen to be the defaults.
Currently sprites are drawn in the default background attributes. Allow each sprite to have a color different from the background, obstacles, hero, etc.
URGENT: This issue now is critical for FAMARGON, I have already reached maximum memory size
Also related to #47
The engine should not generate code and/or data for unused features. E.g. if no "items" are used in the game, all item management code should not be included in the final executable.
Solution:
Possible issues:
Refactor special conditions into engine (like La Churrera by Mojon Twins), with different conditions to be checked:
Add 128K sound chip support: WYZtracker, etc.
Update: seems ArkosTracker is the way to go?
Update 2: Pedro Pimienta recommends Vortex Tracker, and that's included in Z88DK out of the box, so I guess it should be the initial option.
Unfortunately Vortex 2 does not allow sound effects mixed with music. Arkos and WYZ do.
Update 3: Arkos can import Vortex files and export Arkos, so this should be way to go: integrate Arkos in RAGE1, music can be created with Vortex and imported by Arkos.
Add sprite Z-planes in GDATA files, for priority drawing
Support 128K memory bank switching for bigger games.
Development is done in branch banked_game_data
A (WIP) design document for this functionality can be found in that branch, in doc/BANKING-DESIGN.md
r1banktool.pl
to manage the bank and TAP layout:
dataset_*.zx0
files in datasets
dir)bank_N.bin
files in banks
directory (to be created). They will be later processed to get TAPs.dataset_map.asm
source file which will be included in the main program. This file maps dataset -> memory bank and start address so that whenever a dataset needs to be loaded, we know where to find it.bank_bins.cfg
which contains the bank numbers in the same order that the BASIC loader is going to load them.banks.cfg
home_dataset
.
game_config
setting (e.g. zx_target
directive, with 48/128
values). For 48
mode, only home_dataset
is compiled, all assets go there and the banking functions are not used. For 128
mode, all functionality from this issue is brought in.USAGE-OVERVIEW.md
with instructions for 48/128 buildsThis issue has originated the following non-trivial design changes:
Allow to specify multiple animation sequences for a sprite:
Development started in branch refactor_animation_and_graphics_data
There are lots of places where the code is generic and uses several pointers to access things, assets, code, etc. Accessing these pointers is easy from C, but it generates lots of assembler code because of the indirections and the intermediate variable needed.
These generality makes sense if the code would be included as a library, since it should be capable of handling different setups. But since currently the RAGE code is designed to be compiled with every build, and it already depends of constants that are defined in game_data.h
(which is generated and completely depends on the concrete game), it turns out that lots of those indirections can be precalculated at compile time with constants.
Example: the code for checking hero movements (i.e. hero is over a hotzone, hero can grab an item, hero can move in any direction, etc.) is generic and allows a hero sprite of any size. But the hero sprite does not change during the game, it is always the same size; this code can thus be optimized by defining some constants for the hero sprite dimensions in game_data.h
, and using them in the code. This will make the code much smaller and quicker (less instructions in a critical path).
Tasks:
hero.c
)bullet.c
)enemy.c
)flow.c
)datagen: add functionality to edit map screens with text-mode strings in a similar way as PIXELS lines in tiles.
doc/MAP-SCREEN-DATA-DESIGN.md
for detailsWhen grabbing an item with ID=2, the game flag F_GAME_GOT_ALL_ITEMS is set, but there is still one item left to be grabbed.
Function inventory_add_item does this check and it does not work properly.
Allow creating sprites by applying mirrors (horizontal/vertical) to PIXEL and MASK data. THis can speed up sprite development from a single set of graphic assets.
Most flags fields are 16 bits, but this is overkill for most situations. The unused extra bytes quickly add up in a game with lots of screens, btiles, enemies, etc.
We'd better make flags 8-bit instead of 16-bit, and also remove all currently unused flags fields in data structures. Some of them were put there "just in case", but we are tight on memory, so we will remove unused ones and add any flags only when needed.
Savings are to be expected in data and also in code, since code for 8-bit checks is normally shorter than 16-bit checks
Tasks:
If hotzone detection is done in flowgen rules, then we can use the already existing checks and actions in combination with hotzones.
How to do it:
check_hotzones
hero_check_if_inside_hotzones
Add LOAD sprite type for better performance. In games with black bacgground and sprites that avoid obstacles, this can make the game have much better performance
Add support for platform games in side view (i.e. gravity and floor detection support).
Since obstacle detection is already implemented (it's in the basics), only gravity management needs to be done. The platforms are obstacles.
Notes:
Several objects that appear in screens are drawn via BTiles (obstacles, decorations and items). THey normally have a NAME field which references the BTILE whith souhd be used to draw the object. THis blurs the distinction between the object and the tile, which is problematic because the same BTILE can be reused for several objects.
Objects and btiles should differentiated:
Hi Jorge,
I have a simple question about your Sound system.
Why haven't you used the beepfx library (there are available into the z88dk) ? Instead that, you have extrated the asm code and you have included into your game. What's the benefict ?
thanks in advance.
Sprites are currently managed this way:
Drawbacks:
Change to:
Benefits:
Currently there can be one BACKGROUND element in a given map screen, defined as a rectangle which is completely with one given tile of type DECORATION. These background tiles are currently statically generated by DATAGEN.
It would be nice to add a PROBABILITY setting, which applies the same filling algorithm to the given rectangle, but which finally puts the BG tile or not depending on its PROBABILITY. This can make for nice screens with randomly placed background elements (e.g. stars on the sky, grass on the floor, trees, etc.)
PROBABILITY can be a 0-255 setting specified in the BACKGROUND directive in GDATA file for the given map screen. When placing a background element, a random number 0-255 can be generated. If it is less or equal than PROBABILITY, then the tile is drawn. If it is greater, it is not. This way, 0-255 maps exactly to the regular probability interval (0,1), with 0 = never show and 1 = always show.
Finally, this code should be added to the engine and removed from DATAGEN. Memory wise, it's much cheaper to include a definition of a rectangle, btile and probability than several dozens of automatically generated static background tiles. For this, a "background" section should be added to the map_screen_s structure, and the relevant code to use it for drawing the map screen.
Also for this to work we need a pseudo random number generator.
In GAME_CONFIG, SCREEN line is INITIAL=1, it should be INITIAL=Screen02 and DATAGEN modified to output screen indexes into game_data.h
based on screen name.
Some game assets (e.g. btiles, enemies,...) have some kind of state which is reset at game startup, and changes during the game (flags
field, movement coordinates, etc.); this state is currently stored in the asset definition structure for some asset types.
This is fine when the assets don't "move" in memory; but when memory banking is introduced, assets are stored compressed in "read-only" memory and can reloaded to the working memory zone at ay time. That state would then get reset when switching out a dataset and bringing it back in later.
The general problem is that Asset configuration and state are intermixed in the same data structures. All asset types need to be audited and any state extracted out of them and instead added to game_state
structure.
Goals:
game_state
and removed from struct map_screen_s
Steps:
struct map_screen_s
:
enemy_data
(they can be killed) - Reviewed: flags, movementbtile_data
(they can be enabled/disabled) - Reviewed: flagsstate_data
(screen flags can change) - Reviewed: flagsitem_data
(they can be grabbed) - Reviewed: no state data (item state is held in inventory
global var)hotzone_data
(they can be enabled/disabled) - Reviewed: flagsstruct map_screen_s
to entries in screen asset state tables:
enemy_data
btile_data
flags
(removed, since state number 0 is always reserved for the screen state)hotzone_data
For detailed solution, see section Issues with banked screen data and asset state during the game in doc/BANKING-DESIGN.md
Tasks:
In HOTZONE definition, the current behaviour is: position with ROW,COL params, dimension with WIDTH, HEIGHT params. Numbers are in char-cells.
Additionally we want:
Add user variables in flow rule checks and actions
uint8_t
uint8_t
)Nomenclature for enemies in screens is confusing: they are called "sprites" but they should be named "enemies". This makes code difficult to read and modify.
In order to enable data banking in the extra memory banks of the ZX 128, all game assets need to be accessed via pointers that are changed whenever a bank change is needed. Tasks:
Make the hero have a sprite/animation sequence for the steady state.
branch: sprite_with_steady_position
Currently, items in C code are generated as a global item list, and pointers to items in the screens that contain them. This is the correct approach.
In the generation tool datagen.pl, items are stored inside the screens, and the global item list contains pointers to the items in the screens.
datagen.pl needs to be fixed to store the items the same way as the generated C code.
Currently, we can "draw" a screen layout with text characters, digraphs,etc. and the SCREEN_DATA directive.
We could have an enhanced version of that which would allow:
Make DATAGEN tool strictly check the syntax of the input files and elements according to the documentation, so that errors are more informative and can be more easily solved.
Design:
die
calls during code generations are due to data definition errors. It there are some cases of this, the checks and errors should be moved to the functions before code generation.die
's allowed are those for no write access, error writing files, etc. but we must be sure that the game data can be correctly generated with the data that has been read from the GDATA files.datagen.pl
let's say, -v
(for "verification"), or reuse -c
(for "check") to indicate that we only want to check the syntax of the GDATA filesdatagen.pl
we can check this flag just before the data generation functions, and end with a success message if it was supplied. If we reach that place, it means that GDATA file loading was successful, since if not we would have die
'd in previous functions.Tasks:
datagen.pl
. Add new checks if needed to the data input stage.Add support for multiplayer
Besides the TT_DECORATION and TT_OBSTACLE btile types, there should btiles that kill you when you touch them. This new type makes a good match for #35 , so that the player can be aware that something that moves might kill the hero.
Proposed new type: TT_HARMFUL
Refactor sound generation and just include the player. Include sounds
in .gdata files, so that only used sounds are generated and included in
the final game
Idea: define a sound bank first, then assign sounds from the bank somewhere else
Screen areas (game_area, lives_area, inventory_area) are not configurable but fixed. They need to be specified in GAME_CONFIG object and split out from the engine.
If it is not done, updating the engine will overwrite the screen area definitions if they are change from the library default.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.