initial commit

This commit is contained in:
lee2sman 2021-03-05 04:23:47 -05:00
commit 3d2ec4e4ec
7 changed files with 263 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/node_modules
package_lock.json

44
NOTES.md Normal file
View File

@ -0,0 +1,44 @@
# NOTES
# Day 1
holy smokes
uses yargs
* currently writes all ..... to dungeon file, and separately stores player position in gamefile
* maybe terrain can be written to dungeon file but items location, monster location, temple locations stored in gamefile
* only allow one move a day? (based on date save)
* what's the point?
* why does someone come back?
### To play
create new game file / dungeon
```
node dotd --new
```
move right (for example)
```
node dotd -r
```
## Flags
```
-r
-l
-u
-d
```
right, left, up, down
```
--new
```
creates new board (draws dungeon, places player)

10
TODO.md Normal file
View File

@ -0,0 +1,10 @@
# TODO
- [ ] what's the game mechanic / concept? should be one clear concept
- [.] saveFile should actually save json file (as text) with map and all the tiles in each position:
- [X] player position,
- [ ] all monsters,
- [ ] item positions,
- [ ] terrain positions
- [ ] inventory file to save inventory
- [ ] save date and check for today's date (if so, you cannot move, but can you do something else?)

48
devlog.md Normal file
View File

@ -0,0 +1,48 @@
# Day 1
i started by creating a an array of arrays (2d array) to 'hold' the level. i looped through it to assign a blank characters, at first a zero, but now a period. it took me some time to figure out how to properly point to a x,y position properly with this method. argh. lots of trial and error and i copy-pasta one line i didn't really understand from stackoverflow but understand what it outputs and worked backwards. actually, here it goes. this is cool. separately, maybe i can revisit making my own processing-derivative drawing parser in ascii. ok ok, that's a later project. anyway, i can now address a grid of text with x,y coordinates. great. proud of myself! lol. i have a grid of periods.
next i pick a random x,y position on the grid for the player. drop an @ there.
now i save to an external file. i think a core mechanic of my game will be that you can only play one move a day. inpsired by michael brough's vesper.5 'ritual'-game where you can (only move one square a day). that game got a lot of notice. oh, but it wasn't ascii. and it was 7 or 8 years ago. argh. anyway. i think i like this idea. and it's doable. and even though the command line and ascii art does not appeal to my 'art' base, my hacker phreaks like this, and i like this too! lol. it's not visual though. michael's work is so appealing because it speaks its own visual language. should i just work in p5 again? i have a half-engine for roguelikes in p5. maybe i could revisit? but way, i like this idea of a "Message of the Day" (Dungeon of the Day?) roguelike where it's in the command line, since that's my primary interface on my computer. i mean i'm typing in the command line now.
the concept is loosely that it's an ambient game. when you open a new terminal window the board (perhaps) is displayed as the message of the day. you can make one move a day. (how?). other than moving, maybe you can also use an item, talk to npc's, buy something at the market? or maybe you can move up to 3 different characters, like Lost Vikings (o.g. nintendo game that i liked that there doesn't seem to be any modern clones of).
okay, need to figure out more core mechanic/compelling gameplay. an ambient game is nice perhaps but needs some juice to make people want to play this and not skip over it.
other roguelike ideas i'd been thinking of but maybe not this time:
- monome teletype-based roguelike for my modular synth. moving/fighting/spells would each play a different sound. i wish i could plug a nintendo/snes controller though instead of a keyboard. i guess i could use a numpad instead. each number to trigger a different script, for each direction and maybe 0 for something.
- use p5.js to make more out-there experimental compelling visuals, a la a Broughlike
- use Lua. which i really enjoy, and there are (brough-like again!) tutorials for
- use pico-8 which i also enjoy, and is a subset of Lua with extended API, and i have some tutorials and previous experience on. i particularly love how it combines a CLI with visuals on same screen. i wish i could do this with p5/js.
- use my PLOGO logo-language to make a roguelike. kind of a funny idea. also, i did built a console into it.
anyway.... no end of (bad) ideas
# Day 1 1/2
What should terrain look like?
Old PETSCII? ZZT? (Can i get this with unicode or do i need to load a special font in the terminal, and then have to package that font? Can node do this?
oh wait, or should i just do this. it's easy. emoji.
```
🎄
🌳
🌲
🌴
🎋
🏡
🌱
🌿
🏕️
```
too cheesy? possibly
-
- code page 437 - (for example in ZZT)
- [page 437 characters translated to unicode](https://wikimili.com/en/Code_page_437)
- [unicode page 437 font](https://github.com/berenddeschouwer/fourthreeseven) to work in linux!
- embedded (copy-pastable) in [this article](https://www.masswerk.at/nowgobang/2020/petscii)
- [petscii to unicode converter](https://style64.org/petscii/)

153
dotd.js Normal file
View File

@ -0,0 +1,153 @@
#!/usr/bin/env node
const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const argv = yargs(hideBin(process.argv)).argv
const fs = require("fs");
const dungeonFile = "dungeonfile.txt";
const gameFile = "gamefile.txt";
//globals
const width = 60;
const height = 5;
let dungeon;
let player = {"position": {
"x": null,
"y": null,
}
};
let parseArgs = () => {
if (argv.new){
console.log('new game');
createDungeon();
placePlayer();
} else {
loadDungeon();
loadPlayer();
movePlayer();
}
}
let loadDungeon = () => {
const dungeonInput = fs.readFileSync(dungeonFile,'utf8')
let dungeonRows = dungeonInput.split("\n");
dungeon = Array.from(Array(height), () => new Array(width))
for (let y = 0; y < dungeonRows.length-1; y++){
for (x = 0; x < dungeonRows[0].length; x++){ //length of any string (width of dungeon)
let dungeonRowArr = dungeonRows[y].split("");
dungeon[y][x] = dungeonRowArr[x];
}
}
}
let loadPlayer = () => {
const playerFile = fs.readFileSync(gameFile,'utf8')
player = JSON.parse(playerFile);
}
let movePlayer = () => {
if (argv.r){
if (player.position.x < width-1){
console.log('moved right');
player.position.x++;
} else {
console.log("can't go that way");
}
} else if (argv.l){
if (player.position.x > 0){
console.log('moved left');
player.position.x--;
} else {
console.log("can't go that way");
}
} else if (argv.u){
if (player.position.y>0){
console.log('moved up');
player.position.y--;
} else {
console.log("can't go that way");
}
} else if (argv.d){
if (player.position.y<height-1){
console.log('moved down');
player.position.y++;
} else {
console.log("can't go that way");
}
}
}
let createDungeon = () => {
dungeon = Array.from(Array(height), () => new Array(width))
for (let y = 0; y < height; y++){
for (let x = 0; x < width; x++){
dungeon[y][x] = ".";
}
}
}
let placePlayer = () => {
player.position.x = Math.floor(Math.random()*width)
player.position.y = Math.floor(Math.random()*height)
//dungeon[player.position.y][player.position.x] = "@"
}
let debug = () => {
//console.log(dungeon)
console.log("terminal width: "+process.stdout.columns+" height: "+process.stdout.rows);
console.log("game width: "+width+" height: "+height);
console.log("x: "+player.position.x+" y: "+player.position.y)
}
let dungeonToStrings = () => {
let dungeonStr = "";
for (let i = 0; i < height; i++){
dungeonStr+=(dungeon[i].join("")+"\n");
}
return dungeonStr;
}
let dungeonWithItemsToStrings = () => {
dungeon[player.position.y][player.position.x] = "@"
let dungeonStr = "";
for (let i = 0; i < height; i++){
dungeonStr+=(dungeon[i].join("")+"\n");
}
return dungeonStr;
}
let drawDungeon = dungeonStr => {
console.log(dungeonStr); //display
}
let writeToFile = dungeonStr => {
fs.writeFileSync(dungeonFile, dungeonStr); //save to disk
let playerData = JSON.stringify(player);
fs.writeFileSync(gameFile, playerData); //save to disk
}
let main = () => {
parseArgs();
let dungeonStr = dungeonToStrings();
writeToFile(dungeonStr);
let dungeonWithItems = dungeonWithItemsToStrings();
drawDungeon(dungeonWithItems);
//debug();
}
main()

5
dungeonfile.txt Normal file
View File

@ -0,0 +1,5 @@
............................................................
............................................................
............................................................
............................................................
............................................................

1
gamefile.txt Normal file
View File

@ -0,0 +1 @@
{"position":{"x":29,"y":2}}