Jump to content
IGNORED

Paddle Party Development Diary


Recommended Posts

Also, with all this "creeping featuritus", it looks like my dream of fitting into 16k words is fading fast. I guess it's time to learn about cart.mac....

 

Catsfolly

 

I know what you mean. I went through the same realization, and it was a real shock to my expectations when I broke out the 16K word ROM layout.

 

However, once I came to terms with it and allowed myself to absolutely ignore the ROM size completely, things changed for the better. When I accepted the fact that I had "all the DECLEs I could ever want for anything," that's when my animation sequences flourished into fancy and elaborate cartoons.

 

I admit that my code is bloated and my animation technique is so primitive, it consumes large amounts of ROM for the smallest details. I'm now down to 8.8K left out of the 42K layout, mostly taken by animation graphic tiles. That's unconscionable! And I'm ashamed of it. :(

 

On the other hand, it allowed me to concentrate on what's really important: making the game fun and cool. :)

 

-dZ.

 

Game play is number 1. You are right.

 

But, I think I just need like 17k-18k. But I wanted to fit in 16k if possible...

 

Hey, do you remember one time you explained me how I could have different variable names for the same memory locations using cart.mac?

I remember you showed me a trick where you set some kind of "bookmark" (an equ or symbol) , and then "rewound" the memory macros ("scratch") in some way.

 

It seemed clear at the time, but now I can't find the explanation...

 

Thanks,

 

Catsfolly

Link to comment
Share on other sites

More Trail experiments

 

My research into trailing edge technology continues:

 

I tried different colors to get a fade-out effect (thanks for the suggestions...)

 

The best colors (for my light blue background) appear to be white, tan, and gray.

 

Here is how it looks:

 

post-14916-0-07204100-1340547860.gif

 

I also tried erasing half the pixels in the trailing image circle (creating a kind of dotted line effect).

This makes for a more subtle effect, but also exposes the Intellivision's blockiness.

 

Here is an example:

 

post-14916-0-28798000-1340547972.gif

 

What do you think? Am I on the right trail?

 

Catsfolly

 

I like both of these, but my son and I vote for the different colour fade out with full circles. I also agree that the net looks pretty big, maybe a bit smaller?

Link to comment
Share on other sites

Hey, do you remember one time you explained me how I could have different variable names for the same memory locations using cart.mac?

I remember you showed me a trick where you set some kind of "bookmark" (an equ or symbol) , and then "rewound" the memory macros ("scratch") in some way.

 

It seemed clear at the time, but now I can't find the explanation...

 

Thanks,

 

Catsfolly

 

Catsfolly,

 

It only works if you define all your variables using the CART.MAC macros (e.g., SCRATCH, SYSTEM, BYTEVAR, WORDVAR, etc.). CART.MAC keeps a cursor pointing to the last allocated memory in Scratch RAM (.SCRMEM) and System RAM (.SYSMEM). The trick is to manipulate this variable directly.

 

For instance, at the point I want to enable an overlap of memory blocks, I mark the address of the cursors like this:

 

; Keep track of the current RAM blocks used for the "level" state
LVL_SCR_START   EQU	 .SCRMEM
LVL_SYS_START   EQU	 .SYSMEM

 

I then continue allocating memory normally with the CART.MAC macros. To overlap this block, I just reset the cursors back to the pointers I marked:

 

; Overlap "level" memory
.SCRMEM   SET	 LVL_SCR_START
.SYSMEM   SET	 LVL_SYS_START

 

Now, any new allocations will happen on the same block.

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

By the way, it should be obvious that if you overlap RAM blocks in such a way, neither CART.MAC nor the assembler will tell you when you overrun a block and spill into some unintended memory.

 

It would be better to support "RAM Segments" directly in the framework by using the convenient symbol-arrays that as1600 supports. Indeed, this is the approach that I plan on taking in the next version of P-Machinery.

 

The idea is that you can say something like this (mind you, this is just an example out of the top of my head. I haven't fleshed it out well enough):

 


DEFINE_RAM_SEG(LEVEL, global)   ; Define a new RAM segment with global scope
       ; These variables are available globally
       ; on all machine states
SCORE   SYSTEM  2
LIVES   SCRATCH 1

DEFINE_RAM_SEG(LEVEL, state)    ; Define a new RAM segment with machine state scope
       ; These variables belong to segment "LEVEL"
FOO     SCRATCH 1
BAR     SCRATCH 1

DEFINE_RAM_SEG(PRACTICE, state) ; Define a new RAM segment with machine state scope

       ; These variables belong to segment "PRACTICE"
BAZ     SYSTEM  2
FRED    SYSTEM  2

 

The DEFINE_RAM_SEG() macro would then keep track of the start and size of each RAM segment, attempt to detect overlap and even compute usage per segment to let you know how much RAM you have left per state.

 

The framework would also distinguish between various scopes. For instance, "global" scope cannot be overlapped, while "state" scope can, but it's mutually exclusive with other segments of the same scope.

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

By the way, it should be obvious that if you overlap RAM blocks in such a way, neither CART.MAC nor the assembler will tell you when you overrun a block and spill into some unintended memory.

 

It would be better to support "RAM Segments" directly in the framework by using the convenient symbol-arrays that as1600 supports. Indeed, this is the approach that I plan on taking in the next version of P-Machinery.

 

The idea is that you can say something like this (mind you, this is just an example out of the top of my head. I haven't fleshed it out well enough):

 


DEFINE_RAM_SEG(LEVEL, global)   ; Define a new RAM segment with global scope
	; These variables are available globally
	; on all machine states
SCORE   SYSTEM  2
LIVES   SCRATCH 1

DEFINE_RAM_SEG(LEVEL, state)	; Define a new RAM segment with machine state scope
	; These variables belong to segment "LEVEL"
FOO	 SCRATCH 1
BAR	 SCRATCH 1

DEFINE_RAM_SEG(PRACTICE, state) ; Define a new RAM segment with machine state scope

	; These variables belong to segment "PRACTICE"
BAZ	 SYSTEM  2
FRED	SYSTEM  2

 

The DEFINE_RAM_SEG() macro would then keep track of the start and size of each RAM segment, attempt to detect overlap and even compute usage per segment to let you know how much RAM you have left per state.

 

The framework would also distinguish between various scopes. For instance, "global" scope cannot be overlapped, while "state" scope can, but it's mutually exclusive with other segments of the same scope.

 

-dZ.

Sounds like a pretty slick system. My needs are not so complex at this time. I think the approach you are using now will work fine for me.

 

On the other hand, it would be nice if the system automatically kept track of available ram and unwanted overlaps. I'll give it some more thought.

 

Thanks for the cart.mac help.

 

Catsfolly

Link to comment
Share on other sites

Converting to "cart.mac" the adventure...

 

Okay, so I finally decided I can't keep adding features and fixing bugs in Paddle Party and expect it to fit in 16k words.

 

Up to now, I've relied on T.T.T.T.T. (Time Tested Tagalong Todd Technology). But, if I want more memory I need Joe's cart.mac.

 

Using the cart.mac file will allow me to use a 42K words memory size. Twice the memory and more!!!

 

So, here goes...

 

I read the documentation and it sounded straightforward:

 

1. Include the magic "cart.mac" file. Set up the header.

2. Change all the "RMB" instructions in the code to "SCRATCH" and "SYSTEM" for 8 bit and 16 bit variables.

3. Use dZ's trick to have overlapping variables for different games.

4. Change the "ORG" statements to "ROMSEG".

5. Start filling up the new memory!!! :-)

 

But, I had a few problems -

 

1. With cart.mac, I could no longer have my automatic retro-Intellivision title screen. So, I have to write a title screen. Since the title screen is mostly text, and I was replacing most of the original title screen text anyway, this is no big deal - just another thing to do...

 

2. Next, the program was crashing, because the interrupt service vector wasn't set right.

 

My first 2 variables in 8 bit ram were the interrupt service vector (ISR) . In the Taglong Todd version these got assigned to memory location $100, which is where the exec program dictates they have to be. But the cart.mac version, my ISR variable was set to 102 - which is the first location that the SCRATCH macro manages. This is useless.

 

So, I took out the ISR SCRATCH variable, and made equ's to point to the real ISR at $100.

 

3. All the games still crashed. The problem was that the names of struct-like "PROC" blocks are no longer assigned the same address as the first element of the structure.

 

For example, in the Tagalong todd version:

 

0x343				  PLYR		PROC
0x343				  @@XP		RMB	 1			   ; X position
0x344				  @@YP		RMB	 1			   ; Y position
0x345				  @@XV		RMB	 1			   ; X velocity
0x346				  @@YV		RMB	 1			   ; Y velocity
0x347				  @@TXV	   RMB	 1			   ; Target X velocity
0x348				  @@TYV	   RMB	 1			   ; Target Y velocity
		   ENDP

 

The label "PLYR" has the same value as PLYR.XP (in this case 0x343).

But in the new cart.mac version:

 

0x5026				 PLYR		PROC
  ;@@XP		SYSTEM	 1			   ; X position
0x343				  @@XP		EQU	 .SYSMEM
  ;@@YP		SYSTEM	 1			   ; Y position
0x344				  @@YP		EQU	 .SYSMEM
  ;@@XV		SYSTEM	 1			   ; X velocity
0x345				  @@XV		EQU	 .SYSMEM
  ;@@YV		SYSTEM	 1			   ; Y velocity
0x346				  @@YV		EQU	 .SYSMEM
  ;@@TXV	   SYSTEM	 1			   ; Target X velocity
0x347				  @@TXV	   EQU	 .SYSMEM
  ;@@TYV	   SYSTEM	 1			   ; Target Y velocity
0x348				  @@TYV	   EQU	 .SYSMEM
		   ENDP

 

The PLYR symbol has a value of the next available rom location (0x5026) , which is completely unrelated to the first element of the data structure (which is at 0x343).

 

So, in my code I would do things like this:

 

 mvii  #PLYR,r3
 call  hball_collide

 

Which would fail. I did this in more places than I would have ever imagined (for the player and todd and the tennis balls)

So, I changed them all to look like this

 

 mvii  #PLYR.XP,r3
 call  hball_collide

 

And now I am back in business (except I need a title screen),

 

Catsfolly

Link to comment
Share on other sites

1. With cart.mac, I could no longer have my automatic retro-Intellivision title screen. So, I have to write a title screen. Since the title screen is mostly text, and I was replacing most of the original title screen text anyway, this is no big deal - just another thing to do...

 

Yes you can. As a matter of fact, you set the title string in the ROMSETUP macro for the ROM header. It displays the title screen and then jumps to your MAIN routine (defined also in the ROMSETUP macro). That's what I do in the P-Machinery test and in Christmas Carol, although in the latter I overwrite some of the text with my own custom routine.

 

2. Next, the program was crashing, because the interrupt service vector wasn't set right.

 

My first 2 variables in 8 bit ram were the interrupt service vector (ISR) . In the Taglong Todd version these got assigned to memory location $100, which is where the exec program dictates they have to be. But the cart.mac version, my ISR variable was set to 102 - which is the first location that the SCRATCH macro manages. This is useless.

 

So, I took out the ISR SCRATCH variable, and made equ's to point to the real ISR at $100.

 

The interrupt service vector is a double-byte address starting at $100. This is defined by the EXEC, which has control of VBLANK, so you can't change that. In P-Machinery (and Carol) I encapsulate setting an ISR with a macro. The labels I use to mark the vector are just EQU constants as opposed to actual variables.

 

Moreover, at the end of your ISR, you must return control to the EXEC dispatcher, which resides in address $1014. I also use a macro that gives the feel like a "return" statement.

 

Attached is the ISR macro library from P-Machinery.

 

3. All the games still crashed. The problem was that the names of struct-like "PROC" blocks are no longer assigned the same address as the first element of the structure.

 

They most certainly do. The assembler keeps track of the last instruction address and assigns it to the label of the PROC block. However, keep in mind that when you use the SCRATCH or SYSTEM macros, you are not allocating memory in your current ROM address space, but in Scratch or System RAM, respectively.

 

In essence, the macros expand to a mere EQU pointing to the .SCRMEM or .SYSMEM cursors that CART.MAC maintains. In such cases, you don't really want to use PROC, because you are not defining a "code" block, but a set of constants to be used together. I therefore use the following pattern:

 

FOO     STRUCT 0    ; "0" means ignore the starting address
@@var1  SCRATCH 1
@@var2  SCRATCH 1
@@var3  SCRATCH 1
       ENDS

 

Notice that "STRUCT" does not alter the assembler's instruction pointer, it just groups the fields logically. I just leave the "PROC" blocks for when I want to contain data structures in ROM, such as look-up tables.

 


;; ======================================================================== ;;
;;  LVL_FUNC_TBL: Level function dispatch table.                            ;;
;; ======================================================================== ;;
LVL_FUNC_TBL    PROC
               ;     +-----------------------+---------------------+
               ;     | Normal Level:         | Boss Level:         |
               ;     +-----------------------+---------------------+
@@Init:         DECLE   INIT_NRM_LVL,           INIT_BOSS_LVL
@@Start:        DECLE   START_NRM_LVL,          START_BOSS_LVL
@@End:          DECLE   END_NRM_STAGE,          END_BOSS_STAGE
@@Enemy1:       DECLE   INIT_LVL_GHOST,         INIT_LVL_BADTOY
@@Enemy2:       DECLE   INIT_LVL_SNOMN,         INIT_LVL_SNOBAL
               ENDP

 

The data is contiguous, and inserted "in-line" into the rest of the assemblage.

 

Alternatively, if you want the label to the structure to point to the first element, you must then set the starting address of the structure to the current CART.MAC memory cursor. Again, using STRUC instead of PROC so as not to change the assembler instruction pointer:

 


FOO     STRUCT .SCRMEM    ; "FOO" will point to "FOO.var1"
@@var1  SCRATCH 1
@@var2  SCRATCH 1
@@var3  SCRATCH 1
       ENDS

 

However, we now enter into "abstraction leakage" territory: Is the label supposed to be the address of the first field, or just the grouping name of the record? What if you want your structure to mix Scratch and System RAM? Or worse, what if you want to add a few DECLEs to the record? The labels will still not be contiguous in address space, so why do this? Just make sure to address the specific field that you want, which is actually what you defined them for.

 

And now I am back in business (except I need a title screen),

 

The standard Mattel title screen is there, the EXEC generates it and then calls your MAIN routine, you just need not clear the screen at that point.

 

If you're having trouble with it, let me know. I'll provide some code.

 

-dZ.

isr_util.mac.zip

Edited by DZ-Jay
Link to comment
Share on other sites

And now I am back in business (except I need a title screen),

The standard Mattel title screen is there, the EXEC generates it and then calls your MAIN routine, you just need not clear the screen at that point.

 

If you're having trouble with it, let me know. I'll provide some code.

 

-dZ.

 

Thanks dZ.

 

I see my problem now - things just work differently under cart.mac

 

In Tagalong Todd, I put two addresses in the header - a "title" subroutine and a "main" routine.

 

The Exec:

1. Draws the default title screen.

2. Calls my title subroutine to fix it up.

3. Displays the title screen and waits for controller input.

4. When the controller is pressed, jumps to the main routine.

 

Under cart.mac, only the "main" routine is supplied to the header.

 

The Exec:

1. Draws the default title screen.

2. Jumps to the main routine.

 

So, I need to create a "title screen state" in my code, where the code waits for controller input.

 

Thanks,

 

Catsfolly

Link to comment
Share on other sites

And now I am back in business (except I need a title screen),

The standard Mattel title screen is there, the EXEC generates it and then calls your MAIN routine, you just need not clear the screen at that point.

 

If you're having trouble with it, let me know. I'll provide some code.

 

-dZ.

 

Thanks dZ.

 

I see my problem now - things just work differently under cart.mac

 

In Tagalong Todd, I put two addresses in the header - a "title" subroutine and a "main" routine.

 

The Exec:

1. Draws the default title screen.

2. Calls my title subroutine to fix it up.

3. Displays the title screen and waits for controller input.

4. When the controller is pressed, jumps to the main routine.

 

Under cart.mac, only the "main" routine is supplied to the header.

 

The Exec:

1. Draws the default title screen.

2. Jumps to the main routine.

 

So, I need to create a "title screen state" in my code, where the code waits for controller input.

 

Thanks,

 

Catsfolly

 

You're right. I'm sorry, I should have mentioned that.

 

-dZ.

Link to comment
Share on other sites

 

The label "PLYR" has the same value as PLYR.XP (in this case 0x343).

But in the new cart.mac version:

 

0x5026				 PLYR		PROC
  ;@@XP		SYSTEM	 1			   ; X position
0x343				  @@XP		EQU	 .SYSMEM
  ;@@YP		SYSTEM	 1			   ; Y position
0x344				  @@YP		EQU	 .SYSMEM
  ;@@XV		SYSTEM	 1			   ; X velocity
0x345				  @@XV		EQU	 .SYSMEM
  ;@@YV		SYSTEM	 1			   ; Y velocity
0x346				  @@YV		EQU	 .SYSMEM
  ;@@TXV	   SYSTEM	 1			   ; Target X velocity
0x347				  @@TXV	   EQU	 .SYSMEM
  ;@@TYV	   SYSTEM	 1			   ; Target Y velocity
0x348				  @@TYV	   EQU	 .SYSMEM
		   ENDP

 

The PLYR symbol has a value of the next available rom location (0x5026) , which is completely unrelated to the first element of the data structure (which is at 0x343).

 

 

Ah yes. I really ought to do something to make it easier to allocate structures in RAM. The STRUCT/ENDS keywords help you a *little* here, although less than you might hope.

 

What I've started doing is something more like this:

;  Define a structure that exists only to hold offset information relative to its start
REC1            STRUCT  0
@@field1        EQU         0       ; This field takes 1 word
@@field2        EQU         1       ; This field takes 1 word
@@field3        EQU         2       ; This field takes 1 word
@@array1        EQU         3       ; This field takes 3 words

@@sizeof        EQU         6       ; By convention, records size of the struct
               ENDS

REC1CNT         EQU         8       ; Number of REC1s in REC2

; This is a second structure that also contains instances of the first structure
REC2            STRUCT  0
@@field1        EQU         0       ; This field takes 1 word
@@array1        EQU         1       ; This field takes 2 words
@@table1        EQU         3       ; This is a table of REC1CNT records of type REC1

@@table1_sz     EQU         REC1.sizeof * REC1CNT
@@sizeof        EQU         3 + @@table1_sz
               ENDS

 

And then later to declare storage, I do things like this:

 

; Declare contiguous storage for 4 REC2 instances, plus 2 other variables
CONTIG          SYSTEM      REC2.sizeof * 4 + 2
VAR0            EQU         CONTIG + 0 ; Variable 0
VAR1            EQU         CONTIG + 1 ; Variable 1
REC2TBL         EQU         CONTIG + 2 ; Array of REC2 structures

 

BTW, all of the above is directly adapted from some code I wrote recently. I've just anonymized the record names and comments to show the structure. And yes, I'm really allocating that much RAM... JLP's 8K words of RAM make it easy. :-)

 

In the actual code, I originally did normal array indexing with constant multiplies and so forth. The attached "mpyk.mac" makes it easy to multiply by small constants and get a reasonable series of shifts and adds. However, I was able to eliminate all those in the final version of my code.

 

Anyway, coming back to your example, You might consider recoding your PROC as a STRUCT, doing something like this:

 

           WORDARRAY   PLYR, 6
           STRUCT      PLYR
@@XP        EQU         $ + 0         ; X position
@@YP        EQU         $ + 1         ; Y position
@@XV        EQU         $ + 2         ; X velocity
@@YV        EQU         $ + 3         ; Y velocity
@@TXV       EQU         $ + 4         ; Target X velocity
@@TYV       EQU         $ + 5         ; Target Y velocity
           ENDS        

 

This guarantees that the structure remains contiguous, if nothing else. (Note that once JLP RAM is in play with the 42K map, you're not guaranteed that two given allocations will be contiguous unless you allocate with WORDARRAY or BYTEARRAY.)

mpyk.zip

Edited by intvnut
Link to comment
Share on other sites

  • 3 weeks later...

Tennis on a Grid?

 

In Asteroids, Lunar Lander, Gravitar, and other classic space games, when the player pushes on the controller, a force is applied to their spaceship. This causes the spaceship to move.

 

When the controller is released, the spaceship doesn't stop - it continues to move in the same direction until some counterforce is applied.

 

My game "Tennis in Space" works like this. But apparently some people are not "getting" the fact that the spaceship (flying tennis court) continues to move even though they have released the controls.

 

So I get comments like "A meteor shot out from the side and hit my ship". Actually the meteors only move downward, so this says to me that the player didn't realize that their ship was moving sideways at high speed.

 

In the early levels of "Tennis in Space" there are few objects on the screen, so the best way for the player to know how their ship is moving is to look at the starfield. If the stars are zooming towards the right, it means the ship is moving to the left. If the stars are zooming towards the left, it means the ship is moving to the right. If the stars are moving downward, it means the ship is moving straight ahead.

 

But, perhaps scrolling starfields have been used as "eye candy" by so many games that players are conditioned to just ignore them.

 

The question is "How can I let the player know that they are moving sideways?"

 

As an experiment, I tried a different background. I did a grid because that was the easiest thing to try. It's not as pretty as the starfield, but maybe it makes the motion easier to understand. (The red flames appear on the sides of the "flying tennis court" when the player is pushing on the controls...).

 

post-14916-0-04796300-1343278898.gif

 

What do you think? (The grid just an example to stimulate ideas and feedback…)

 

Is there anything else I could do to give the player a sense of motion?

 

Thanks for thinking about it,

 

Catsfolly

Link to comment
Share on other sites

How about an alien audience watching the match in the background?

 

Other thoughts (that maybe don't fit in the Tennis is Space idea) if you want to show land at the bottom and have a mountain/scenery in the background move. You could also put the court on "wheels" and show them rolling as well but that would probably require more MOBs that you probably don't have available? If you made it on land, those could be asteroids hitting the planet ...

  • Like 1
Link to comment
Share on other sites

How about an alien audience watching the match in the background?

 

Other thoughts (that maybe don't fit in the Tennis is Space idea) if you want to show land at the bottom and have a mountain/scenery in the background move. You could also put the court on "wheels" and show them rolling as well but that would probably require more MOBs that you probably don't have available? If you made it on land, those could be asteroids hitting the planet ...

 

Yeah, having land at the bottom is a good idea. But currently I am mixing real and "fake" scrolling to make the scene. If I wanted mountains at the bottom I would have to switch to all "fake" scrolling to keep them on the screen. This might limit my color choices for the meteors and satellites. And it would take a lot of work. But it would help make things clear.

 

I have one motion object free when the "flames" are not in use. I am trying to think of the space equivalent of "wheels" - something like a trail or cartoon "speed lines". All are difficult to do with one object...

 

Thanks for your ideas.

Link to comment
Share on other sites

Hmmm... I didn't have any problem understanding the momentum thing at all. It was very similar to other space games like Space Spartans or Space Hawk. The grid seems too harsh.

 

You have some space in the upper right corner; perhaps you can display your heading as a small arrow there?

Link to comment
Share on other sites

Hmmm... I didn't have any problem understanding the momentum thing at all. It was very similar to other space games like Space Spartans or Space Hawk. The grid seems too harsh.

 

You have some space in the upper right corner; perhaps you can display your heading as a small arrow there?

I'm a little worried people might think the arrow is telling them where they should go, rather than the direction they are already going.

I guess it depends on how the arrow is drawn and presented...

 

I'll give it some thought. Thanks,

 

Catsfolly

Link to comment
Share on other sites

  • 3 weeks later...

Arrow bics.

 

Instead of an arrow in the corner of the screen, I decided to try putting a little arrow in front of the spaceship.

 

The arrow shows generally which direction you are going.

 

I merged the side jets and the paddles to cut down on flicker.

 

What do you think?

 

post-14916-0-20068600-1345008202.gif

 

 

Catsfolly

  • Like 1
Link to comment
Share on other sites

Arrow bics.

 

Instead of an arrow in the corner of the screen, I decided to try putting a little arrow in front of the spaceship.

 

The arrow shows generally which direction you are going.

 

I merged the side jets and the paddles to cut down on flicker.

 

What do you think?

 

post-14916-0-20068600-1345008202.gif

 

 

Catsfolly

 

Catsfolly,

 

It looks great, but I must emphasize that the arrows are superfluous. In my opinion, the directional star field gives enough orientation information.

 

I'm also afraid that the arrows may be a bit distracting. The player's attention should focus on the moving paddles and the meteorites, and adding one more moving element competes with that. The star field lies at the fringes of peripheral vision, and should give enough cue.

 

In any case, great work! I can't wait to play it. :)

 

-dZ.

Link to comment
Share on other sites

Thanks everyone for your input and positive comments.

 

I think the arrow helps make it clear which way your ship is going, and in actual gameplay is not confusing.

 

So I will go with it for awhile.

 

If people have trouble with it, maybe I will make it an optional thing.

 

Catsfolly

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...