Page 1 of 1

General Game Design - Early Tests

Posted: Sun Oct 08, 2023 5:17 pm
by ericomont
Hello chaps,
What would be the minimum required capabilities of a language to create games?

Apart from the logic and code control side of things, in my opinion, it needs to be able to both display something (sprite, tile, letter, pixel, etc), and read some input (keyboard, joystick, mouse, etc). At this point, you have the minimum elements to create infinite games. The next step would be sound support, so you have a complete interactive audio visual experience at hand. With these in check, some form of making the game huge in size would be great, something in the form of disk load/save/run.

That being said, I will be experimenting with those topics on this thread. Keep in mind that some of those things might be already in plan for ugBasic, but we have the possibility to address the target machine directly to quite a nice degree, the more options, the better, particularly those that are very peculiar to the Color Computer ;)

Re: General Game Design - Early Tests

Posted: Mon Oct 09, 2023 6:03 pm
by spotlessmind1975
Hi ericomont, excellent arguments! :D

But... are you sure it's a TRS-80 Color Computer theme only? ;)

Re: General Game Design - Early Tests

Posted: Tue Oct 10, 2023 11:13 am
by ericomont
Probably works for all platforms, languages and engines, if considering each peculiarities.

One factor I would also add to the above list is the memory cost of logics in ugBasic.
This part would be a bit tricky to keep track right now but I will keep an eye on it.

So here are the topics: Display - Input - Sound - Disk - Memory

The most standard display is the text mode the computer boots, a 32 x 16 resolution with 256 characters
These 256 characters are divides into 64 text+numbers,64 inverted ones and a set of semigraphics, known as semigraphics 4, they are a set of "tiles" containing 8 colors and they can "fake" the screen as a 64x32 resolution one. The catch is that on each block, you can only have black and one color.

Image

The first step then, is to master this display mode.

In Disk Extended Basic (DECB), the more common way to do things with this mode is with CLS, PRINT and CHR$.
These commands are available in ugBasic, let's see how they fare:
  • At first, I failed to make CLS work, or even CLS GREEN, might need to pop in a ticket on github on this.
  • Second, the print command, works as expected and even triggers the auto scroll.
  • CHR works fine and delivers characters from 32 to 256.
Some considerations: the PRINT command is faster than DECB but not as versatile. Works fine though. The CHR command also works fine but can only reach the characters seen on the last image, it skips the 32 inverted number and symbols.

That being said, within the Color Computer there is one other way to draw those characters, that is by POKEing the screen memory address with the required character value. You would POKE X,Y where X=1024-1535 and y=0-255. The X is the screen coordinate in a single variable, as you reach the right side of the screen, you continue counting on the next line.

The following code will CLS and print the characters using first PRINT CHR and then POKE:

Code: Select all

REM --- TEXT MODE DISPLAY SG4

REM --- PRINT
CLS
TIMER=0
FOR i = 32 TO 256
	PRINT CHR(i);
NEXT
PRINT TIMER;
WAIT KEY

REM --- POKE
CLS
TIMER=0
FOR i = 1024 TO 1279
	POKE i , i-512
NEXT
PRINT:PRINT TIMER;
Notice the output from the pokes display all characters like on this shot:
Image

Also notice that POKEing is ridiculously super fast, to the point that we can just the plot the full screen and create a CLS subroutine of our own :)
Anyways, it seems the standard text mode is under control and performance is very good so far. :)

Re: General Game Design - Early Tests

Posted: Tue Oct 10, 2023 2:11 pm
by ericomont
A bit more playing around with PRINT and POKE.

While the later carries the position within itself, PRINT needs to be pointed to an XY coordinate with LOCALE X,Y.
The following code will fill the screen printing one yellow block at a time, then it will do the same poking red blocks.

Code: Select all

REM --- TEXT MODE DISPLAY SG4
x%=0 : y%=0
CLS

DO
REM --- PRINT
FOR y=0 TO 15
	FOR x=0 TO 31
		LOCATE x,y
		PRINT CHR(159);
	NEXT
NEXT
WAIT KEY

REM --- POKE
FOR x=1024 TO 1535
	POKE x,191
NEXT
WAIT KEY
LOOP
The speed difference between those modes is huge :shock:
Keeping in mind PRINT is compatible with the other systems while this POKing is not, it also does move fast too, just not as fast.
This is what I will be trying to explore, options within ugBasic that are native to the Color Computer.

Both techniques are fine. I will keep PRINT for when text is needed and POKE for fast action things.
Just like on the real machine, printing the last character on screen will trigger an auto scroll which does not happen on POKE.
Also, keep in mind variable auto declarations, it is best to declare them all like the above code, because if I don't, the POKE part will hang.
One last thing, it seems ugBasic defaults to a dark green background where the machine uses the normal green.

With the ability to draw on screen using text and those wonderful semigraphics 4, what would you create?

Re: General Game Design - Early Tests

Posted: Wed Oct 11, 2023 9:31 pm
by spotlessmind1975
Hi ericomont, these are really very interesting posts, thank you! :D
ericomont wrote: Tue Oct 10, 2023 11:13 am One factor I would also add to the above list is the memory cost of logics in ugBasic.
This part would be a bit tricky to keep track right now but I will keep an eye on it.
Regarding memory occupied by logic, targets using the Motorola 6809 CPU (like coco) benefit from a very effective local optimizer ("peephole optimizer"). This can help a lot in game development -- but, of course, I'm working on optimizing the code further. So, stay tuned.
ericomont wrote: Tue Oct 10, 2023 11:13 am At first, I failed to make CLS work, or even CLS GREEN, might need to pop in a ticket on github on this.
Regarding the issues on CLS command, it is not clear to me: in what sense does it not work? CLS clears the screen. Setting a background color depends on hardware. Is there something I am missing?
ericomont wrote: Tue Oct 10, 2023 11:13 am Some considerations: the PRINT command is faster than DECB but not as versatile. Works fine though. The CHR command also works fine but can only reach the characters seen on the last image, it skips the 32 inverted number and symbols.
Regarding PRINT and the limit of the first 32 characters: it must be said that the first 31 characters are reserved for (portable) embedded commands, such as changing the cursor position or changing the color "in line". These commands are portable in the sense that they are available, equally, on all platforms. But I think it's fair to offer a version of the PRINT command that doesn't interpret these characters. I added a ticket specifically on github.
ericomont wrote: Tue Oct 10, 2023 11:13 am That being said, within the Color Computer there is one other way to draw those characters, that is by POKEing the screen memory address with the required character value.
There is a portable way to draw characters on the screen using POKE, and that is to use the TEXTADDRESS variable. This variable keeps the address of the first location of the video memory (in text mode). On coco it is currently equal to 1024, but it could vary if the ugBASIC implementation changes the video segment. It could happen.

To put a character on a specific (x,y) location using POKE, here it is a small routine (it works also on Commodore!):

Code: Select all

PROCEDURE pokeAt[ x, y, c ]
	POKE TEXTADDRESS + ( y * SCREEN COLUMNS ) + x, c
END PROC

pokeAt[ 10, 10, 191 ]
ericomont wrote: Tue Oct 10, 2023 11:13 am Anyways, it seems the standard text mode is under control and performance is very good so far.
I'm really happy to read it! 8-)

Re: General Game Design - Early Tests

Posted: Wed Oct 11, 2023 9:54 pm
by spotlessmind1975
ericomont wrote: Tue Oct 10, 2023 2:11 pm Both techniques are fine. I will keep PRINT for when text is needed and POKE for fast action things.
It seems like a fair strategy to me, alternating PRINT and POKE. If desired, the POKE technique is also (almost) portable -- but only on computers that have a native text mode and a "memory mapped" graphics card, as it happens with the Motorola 6847, MOS VIC, MOS VIC-II, MOS chipsets TED and ATARI GTIA.
ericomont wrote: Tue Oct 10, 2023 2:11 pm Also, keep in mind variable auto declarations, it is best to declare them all like the above code, because if I don't, the POKE part will hang.
On this topic... actually, I believe the problem lies in the initialization of the variables. Initialization of variables occurs using the minimum bitwidth necessary to maintain the value. By writing:

Code: Select all

x=0
...
FOR x=1024 TO 1535
   ...
NEXT
the ugBASIC compiler assigns the value 0, represented as an 8-bit number, to the variable, which becomes an 8-bit variable. The next FOR would "cycle" from 1024 to 1535 on an 8-bit variable. Since the number are larger than 255, they are reduced to 8 bit, so: from 0 to 255. This explains why you don't see anything on the screen -- simply, the program would try to POKE memory from 0 to 255. There is an option in ugBASIC to receive a warning if bits are lost in various conversions. However, by default, it is disabled.
ericomont wrote: Tue Oct 10, 2023 2:11 pm One last thing, it seems ugBasic defaults to a dark green background where the machine uses the normal green.
The "dark green" background should depend on the fill character -- you can change this by changing the EMPTYTILE variable:

Code: Select all

EMPTYTILE=96
CLS]
ericomont wrote: Tue Oct 10, 2023 2:11 pm With the ability to draw on screen using text and those wonderful semigraphics 4, what would you create?
8-) :D

Re: General Game Design - Early Tests

Posted: Thu Oct 12, 2023 5:30 am
by ericomont
Hey, thanks for the info!

The CLS command was not working out of the box as far as I tested, but using the EMPTYTILE worked!
Interesting information about the POKEs, I will give it a try too!
The variable declaration topic I thought it could leave users a bit confused why it would not work.

But what about things that could be done with the ability to draw semigraphics 4 and text on screen?...

OPEN THUGS 1.0! Immerse on an underground dramatic experience!
Available only through advanced AI on the Color Computer.
Image

Here is the code:

Code: Select all

REM --- TEXT MODE DISPLAY SG4
RANDOMIZE:x%=0 : y%=0 : a$="" : b$=""
DIM bkg(512)= #{$80,$80,$80,$80,$80,$a7,$af,$af,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$af,$af,$af,$c5,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$ac,$ad,$af,$af,$af,$af,$af,$af,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$af,$af,$c4,$c2,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$80,$80,$ae,$ad,$af,$af,$af,$a2,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$af,$aa,$ca,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$a1,$a3,$ab,$a3,$a3,$ab,$af,$af,$a2,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$af,$c5,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$a7,$af,$af,$af,$df,$dd,$df,$ac,$ac,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$ab,$c9,$c2,$80,$ff,$ff,$bb,$80,$80,$80,$80,_
				$a7,$af,$af,$80,$df,$df,$80,$da,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$ab,$c4,$c8,$cc,$cc,$bf,$ba,$c3,$c6,$cc,_
				$af,$af,$80,$80,$dd,$df,$df,$da,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$af,$aa,$ff,$ff,$bf,$ba,$80,$80,$80,_
				$af,$ab,$a2,$80,$d4,$df,$da,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$ad,$aa,$bf,$ff,$bf,$a2,$80,$80,$80,_
				$af,$af,$af,$ab,$a2,$dd,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$a8,$fc,$ff,$bf,$ad,$a2,$80,$80,_
				$af,$af,$af,$af,$af,$ab,$a2,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$fc,$bc,$80,$ad,$a2,$80,_
				$ac,$ac,$ac,$ac,$ac,$ac,$ac,$a8,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$98,$98,$98,$80,$80,$ac,$80,_
				$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,_
				$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80}

REM --- DRAW BKG CHARACTERS
EMPTYTILE=128
CLS

FOR x=0 TO 511
	POKE 1024+x, bkg(x)
NEXT

DO

REM --- Mano Courie

WAIT #1000 MILLISECONDS
FOR x=352 TO 511
	POKE 1024+x,128											:REM CLS
NEXT
LOCATE 3,12:PRINT CHR(133);CHR(139);STRING(CHR(143),14);	:REM DRAW DIALOG BOX
LOCATE 4,13:PRINT CHR(141);STRING(CHR(143),14);
LOCATE 5,14:PRINT STRING(CHR(143),14);
LOCATE 5,15:PRINT STRING(CHR(143),14);
x=RND(10)													:REM CHOOSE TEXT
IF x=0 THEN: a$="LIKE I SAID,":b$="ALL FINE"	:ENDIF
IF x=1 THEN: a$="HE TOLD":b$="NOTHING"			:ENDIF
IF x=2 THEN: a$="JONNY WAS":b$="MAD!"			:ENDIF
IF x=3 THEN: a$="DEALT WITH":b$=""				:ENDIF
IF x=4 THEN: a$="THAT WAS AN":b$="AMBUSH!" 		:ENDIF
IF x=5 THEN: a$="ON SCHEDULLE":b$=""			:ENDIF
IF x=6 THEN: a$="NO ONE CAME":b$="OUT"			:ENDIF
IF x=7 THEN: a$="HAPPENED A":b$="COUPLE DAYS"	:ENDIF
IF x=8 THEN: a$="ERICO SOLVED":b$="THAT"		:ENDIF
IF x=9 THEN: a$="TROUBLED":b$="SITUATION!"		:ENDIF
LOCATE 6,13:PRINT a$;										:REM DRAW TEXT
LOCATE 6,14:PRINT b$;
FOR x=0 TO 6												:REM TALKING
	LOCATE 5,7  
	PRINT CHR(222);CHR(216);
	WAIT #150 MILLISECONDS:LOCATE 5,7 
	PRINT CHR(223);CHR(218);
	WAIT #150 MILLISECONDS
NEXT

REM --- Madame Xavasca
WAIT #1000 MILLISECONDS
FOR x=352 TO 511
	POKE 1024+x,128											:REM CLS
NEXT
LOCATE 13,12:PRINT STRING(CHR(143),14);CHR(135);CHR(138);	:REM DRAW DIALOG BOX
LOCATE 13,13:PRINT STRING(CHR(143),14);CHR(142);
LOCATE 13,14:PRINT STRING(CHR(143),14);
LOCATE 13,15:PRINT STRING(CHR(143),14);
x=RND(10)													:REM CHOOSE TEXT
IF x=0 THEN: a$="HOW IS THE":b$="CARGO?"		:ENDIF
IF x=1 THEN: a$="WHAT DID I":b$="TELL YOU?"		:ENDIF
IF x=2 THEN: a$="AND THE JOB?":b$=""			:ENDIF
IF x=3 THEN: a$="DON'T TELL":b$="ME!"			:ENDIF
IF x=4 THEN: a$="GOT THE":b$="PAYBACK?" 		:ENDIF
IF x=5 THEN: a$="VERY WELL":b$=""				:ENDIF
IF x=6 THEN: a$="ABOUT THE":b$="COUNTERFEIT?"	:ENDIF
IF x=7 THEN: a$="ORDER MORE":b$="RESOURCES"		:ENDIF
IF x=8 THEN: a$="FORGET ABOUT":b$="IT!"			:ENDIF
IF x=9 THEN: a$="SHOW WHAT WE":b$="GOT!"		:ENDIF
LOCATE 14,13:PRINT a$;										:REM DRAW TEXT
LOCATE 14,14:PRINT b$;
FOR x=0 TO 6												:REM TALKING
	LOCATE 25,7:PRINT CHR(188);  
	LOCATE 25,8:PRINT CHR(188);
	WAIT #150 MILLISECONDS
	LOCATE 25,7:PRINT CHR(191);
	LOCATE 25,8:REM PRINT CHR(252); 
	WAIT #150 MILLISECONDS
NEXT

LOOP
First, I noticed something strange, look at the almost last line LOCATE 25,8:REM PRINT CHR(252);
Remove the REM and the code will hang, I don't know the reason, happens if CHR is used, seems to be a bug?
Also, am I using the RANDOMIZER correctly? I'd think it would work as RANDOMIZE TIMER for RNDs.

Anyways, by displaying graphics like that means we have a non-linear animation creation and editor system? :p
Feels like it :)

Re: General Game Design - Early Tests

Posted: Thu Oct 12, 2023 8:18 am
by spotlessmind1975
Hi ericomont!

It's a really fantastic animation!
And, for me, it's a wonderful birthday present! :D
ericomont wrote: Thu Oct 12, 2023 5:30 am The CLS command was not working out of the box as far as I tested, but using the EMPTYTILE worked!
Ok, so the explanation is simple. In computers with Motorola 6847 chipset, the color is associated with the ASCII code of the character to be printed (which we should more correctly call "screen code"). In other systems, color is a separate element from characters. Since ugBASIC is isomorphic, it does not guarantee that CLS behaves the same everywhere. Since it is not possible to set a color with that chipset, the color is not set. The solution of using EMPTYTILE is indeed a workaround. It is probably possible to assign a valid EMPTYTILE value for each target of interest.
ericomont wrote: Thu Oct 12, 2023 5:30 am The variable declaration topic I thought it could leave users a bit confused why it would not work.
I agree with you on this, and I have opened a ticket to allow to change the standard behavior, which would be less optimized.
ericomont wrote: Thu Oct 12, 2023 5:30 am First, I noticed something strange, look at the almost last line LOCATE 25,8:REM PRINT CHR(252);
Remove the REM and the code will hang, I don't know the reason, happens if CHR is used, seems to be a bug?
Regarding this problem, it is not really a bug but the program stops execution because it is in an "out of memory" situation because it has run out of space available for dynamic strings. By default, coco target can have a maximum of 32 strings for a maximum total of 512 bytes. To increase the available space, and make it work, use this command on the top of the program:

Code: Select all

DEFINE STRING COUNT 64
For RANDOMIZER it is better to use RANDOMIZE TIMER, but in reality the RND of ugBASIC is already non-deterministic at every call... or, at least, it should be. :)
ericomont wrote: Thu Oct 12, 2023 5:30 am Anyways, by displaying graphics like that means we have a non-linear animation creation and editor system? :p
Wouldn't it be better to use an editing tool, and load the file directly into the vector, like this?
(I'm working on loading binary files)

Code: Select all

DIM bkg(512) = LOAD "bkg.txt" AS TEXT

Re: General Game Design - Early Tests

Posted: Thu Oct 12, 2023 8:44 pm
by ericomont
spotlessmind1975 wrote: Thu Oct 12, 2023 8:18 am ... it's a wonderful birthday present! :D
Nice! I hope you are having a great day!
Regarding this problem, it is not really a bug but the program stops execution because it is in an "out of memory" ...
Ah great! Gotta put that down on a note. I think I stumbled into something similar some months ago and end up forgetting about it.
About RANDOMIZER I will try that. Since this app has a fixed linear time, it seemed to me that the RNDs were showing same sequence every time I ran it.
Wouldn't it be better to use an editing tool, and load the file directly into the vector, like this?
(I'm working on loading binary files)

Code: Select all

DIM bkg(512) = LOAD "bkg.txt" AS TEXT
Yes it would be ace! Also, if able to save/load on target disk, a Paint app would easily be possible.

The idea on OPEN THUGS is to expand the roast of characters and add a bunch of cut scenes.
Since the code is simple, anyone can play along and create stuff for it :)
Will push this project out of here in a new thread as it matures along.

Now, how long would take an uninformed person to realize it is looking at RND and not a story/movie?
Would it matter? Would the experience felt be of less value? Would people fell cheated? ;)