Giter Site home page Giter Site logo

communicationmod's Introduction

CommunicationMod

Slay the Spire mod that provides a protocol for allowing another process to control the game

Requirements

Setup

  1. Copy CommunicationMod.jar to your ModTheSpire mods directory
  2. Run ModTheSpire with CommunicationMod enabled
  3. Edit your newly-created SpireConfig file with the command you want to use with CommunicationMod (see https://github.com/kiooeht/ModTheSpire/wiki/SpireConfig for the location of your config file). Your config file should look something like this (note that certain special characters must be escaped):
#Sat Apr 20 02:49:10 CDT 2019
command=python C\:\\Path\\To\\Script\\main.py

What does this mod do?

CommunicationMod launches a specified process and communicates with this process through stdin and stdout, with the following protocol:

(Note: all messages are assumed to be ended by a new line '\n')

  • After starting the external process, CommunicationMod waits for the process to send "ready" on stdout. If "ready" is not received before a specified timeout, the external process will be terminated.
  • Whenever the state of the game is determined to be stable (no longer changing without external input), CommunicationMod sends a message containing the JSON representation of the current game state to the external process's stdin. For example:
{"available_commands":["play","end","key","click","wait","state"],"ready_for_command":true,"in_game":true,"game_state":{"screen_type":"NONE","screen_state":{},"seed":-3047511808784702860,"combat_state":{"draw_pile":[{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"0560233c-41e8-4620-a474-d0ed627354bd","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"f8adc2a6-4d1c-4524-9044-9e2bfacf4256","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"c6594538-debc-4085-81be-3b20a5d44062","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":false,"cost":-2,"name":"Ascender\u0027s Bane","id":"AscendersBane","type":"CURSE","ethereal":true,"uuid":"da41cd4b-6eda-4020-a031-ad870a52b0e1","upgrades":0,"rarity":"SPECIAL","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"b54d5d98-f074-4f71-b705-f071f1d44fff","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"9c10951d-0c08-46bd-bc5f-be2e1b9d53f2","upgrades":0,"rarity":"BASIC","has_target":false}],"discard_pile":[],"exhaust_pile":[],"cards_discarded_this_turn":0,"times_damaged":0,"monsters":[{"is_gone":false,"move_hits":1,"move_base_damage":12,"half_dead":false,"move_adjusted_damage":-1,"max_hp":46,"intent":"DEBUG","move_id":1,"name":"Jaw Worm","current_hp":1,"block":0,"id":"JawWorm","powers":[]}],"turn":1,"limbo":[],"hand":[{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"7b54caef-9c56-4134-82a2-be8f1d5c435f","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"5f9bba1a-4c54-4be7-b387-1992937c5717","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"0dbea551-c9ae-4228-8821-74e2ffd04889","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"612c16f7-f8f7-4253-88bb-ab4813d34b69","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":2,"name":"Bash","id":"Bash","type":"ATTACK","ethereal":false,"uuid":"41e3754b-d2e3-40b4-a83b-f165b1943ec3","upgrades":0,"rarity":"BASIC","has_target":true}],"player":{"orbs":[],"current_hp":68,"block":0,"max_hp":75,"powers":[],"energy":3}},"deck":[{"exhausts":false,"is_playable":false,"cost":-2,"name":"Ascender\u0027s Bane","id":"AscendersBane","type":"CURSE","ethereal":true,"uuid":"da41cd4b-6eda-4020-a031-ad870a52b0e1","upgrades":0,"rarity":"SPECIAL","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"7b54caef-9c56-4134-82a2-be8f1d5c435f","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"c6594538-debc-4085-81be-3b20a5d44062","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"5f9bba1a-4c54-4be7-b387-1992937c5717","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"0560233c-41e8-4620-a474-d0ed627354bd","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Strike","id":"Strike_R","type":"ATTACK","ethereal":false,"uuid":"b54d5d98-f074-4f71-b705-f071f1d44fff","upgrades":0,"rarity":"BASIC","has_target":true},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"9c10951d-0c08-46bd-bc5f-be2e1b9d53f2","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"0dbea551-c9ae-4228-8821-74e2ffd04889","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"612c16f7-f8f7-4253-88bb-ab4813d34b69","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":1,"name":"Defend","id":"Defend_R","type":"SKILL","ethereal":false,"uuid":"f8adc2a6-4d1c-4524-9044-9e2bfacf4256","upgrades":0,"rarity":"BASIC","has_target":false},{"exhausts":false,"is_playable":true,"cost":2,"name":"Bash","id":"Bash","type":"ATTACK","ethereal":false,"uuid":"41e3754b-d2e3-40b4-a83b-f165b1943ec3","upgrades":0,"rarity":"BASIC","has_target":true}],"relics":[{"name":"Burning Blood","id":"Burning Blood","counter":-1},{"name":"Neow\u0027s Lament","id":"NeowsBlessing","counter":2}],"max_hp":75,"act_boss":"The Guardian","gold":99,"action_phase":"WAITING_ON_USER","act":1,"screen_name":"NONE","room_phase":"COMBAT","is_screen_up":false,"potions":[{"requires_target":false,"can_use":false,"can_discard":false,"name":"Potion Slot","id":"Potion Slot"},{"requires_target":false,"can_use":false,"can_discard":false,"name":"Potion Slot","id":"Potion Slot"}],"current_hp":68,"floor":1,"ascension_level":20,"class":"IRONCLAD","map":[{"symbol":"M","children":[{"x":0,"y":1}],"x":1,"y":0,"parents":[]},{"symbol":"M","children":[{"x":2,"y":1}],"x":2,"y":0,"parents":[]},{"symbol":"M","children":[{"x":4,"y":1}],"x":3,"y":0,"parents":[]},{"symbol":"M","children":[{"x":5,"y":1}],"x":6,"y":0,"parents":[]},{"symbol":"M","children":[{"x":1,"y":2}],"x":0,"y":1,"parents":[]},{"symbol":"M","children":[{"x":1,"y":2},{"x":2,"y":2}],"x":2,"y":1,"parents":[]},{"symbol":"?","children":[{"x":3,"y":2}],"x":4,"y":1,"parents":[]},{"symbol":"$","children":[{"x":4,"y":2}],"x":5,"y":1,"parents":[]},{"symbol":"M","children":[{"x":1,"y":3},{"x":2,"y":3}],"x":1,"y":2,"parents":[]},{"symbol":"?","children":[{"x":2,"y":3},{"x":3,"y":3}],"x":2,"y":2,"parents":[]},{"symbol":"M","children":[{"x":3,"y":3}],"x":3,"y":2,"parents":[]},{"symbol":"M","children":[{"x":5,"y":3}],"x":4,"y":2,"parents":[]},{"symbol":"?","children":[{"x":1,"y":4}],"x":1,"y":3,"parents":[]},{"symbol":"M","children":[{"x":3,"y":4}],"x":2,"y":3,"parents":[]},{"symbol":"?","children":[{"x":3,"y":4}],"x":3,"y":3,"parents":[]},{"symbol":"M","children":[{"x":4,"y":4}],"x":5,"y":3,"parents":[]},{"symbol":"M","children":[{"x":1,"y":5}],"x":1,"y":4,"parents":[]},{"symbol":"?","children":[{"x":2,"y":5},{"x":3,"y":5}],"x":3,"y":4,"parents":[]},{"symbol":"M","children":[{"x":3,"y":5}],"x":4,"y":4,"parents":[]},{"symbol":"E","children":[{"x":1,"y":6}],"x":1,"y":5,"parents":[]},{"symbol":"E","children":[{"x":1,"y":6},{"x":2,"y":6}],"x":2,"y":5,"parents":[]},{"symbol":"R","children":[{"x":2,"y":6},{"x":3,"y":6}],"x":3,"y":5,"parents":[]},{"symbol":"R","children":[{"x":2,"y":7}],"x":1,"y":6,"parents":[]},{"symbol":"M","children":[{"x":2,"y":7},{"x":3,"y":7}],"x":2,"y":6,"parents":[]},{"symbol":"E","children":[{"x":3,"y":7}],"x":3,"y":6,"parents":[]},{"symbol":"E","children":[{"x":1,"y":8},{"x":2,"y":8},{"x":3,"y":8}],"x":2,"y":7,"parents":[]},{"symbol":"R","children":[{"x":3,"y":8}],"x":3,"y":7,"parents":[]},{"symbol":"T","children":[{"x":0,"y":9}],"x":1,"y":8,"parents":[]},{"symbol":"T","children":[{"x":1,"y":9}],"x":2,"y":8,"parents":[]},{"symbol":"T","children":[{"x":2,"y":9},{"x":3,"y":9},{"x":4,"y":9}],"x":3,"y":8,"parents":[]},{"symbol":"R","children":[{"x":1,"y":10}],"x":0,"y":9,"parents":[]},{"symbol":"M","children":[{"x":1,"y":10}],"x":1,"y":9,"parents":[]},{"symbol":"M","children":[{"x":1,"y":10},{"x":3,"y":10}],"x":2,"y":9,"parents":[]},{"symbol":"R","children":[{"x":4,"y":10}],"x":3,"y":9,"parents":[]},{"symbol":"?","children":[{"x":4,"y":10}],"x":4,"y":9,"parents":[]},{"symbol":"?","children":[{"x":0,"y":11},{"x":1,"y":11}],"x":1,"y":10,"parents":[]},{"symbol":"R","children":[{"x":3,"y":11}],"x":3,"y":10,"parents":[]},{"symbol":"E","children":[{"x":3,"y":11},{"x":4,"y":11}],"x":4,"y":10,"parents":[]},{"symbol":"$","children":[{"x":0,"y":12}],"x":0,"y":11,"parents":[]},{"symbol":"M","children":[{"x":1,"y":12}],"x":1,"y":11,"parents":[]},{"symbol":"M","children":[{"x":3,"y":12},{"x":4,"y":12}],"x":3,"y":11,"parents":[]},{"symbol":"?","children":[{"x":4,"y":12}],"x":4,"y":11,"parents":[]},{"symbol":"E","children":[{"x":0,"y":13}],"x":0,"y":12,"parents":[]},{"symbol":"M","children":[{"x":1,"y":13}],"x":1,"y":12,"parents":[]},{"symbol":"?","children":[{"x":3,"y":13}],"x":3,"y":12,"parents":[]},{"symbol":"M","children":[{"x":3,"y":13}],"x":4,"y":12,"parents":[]},{"symbol":"?","children":[{"x":1,"y":14}],"x":0,"y":13,"parents":[]},{"symbol":"M","children":[{"x":1,"y":14}],"x":1,"y":13,"parents":[]},{"symbol":"?","children":[{"x":2,"y":14},{"x":3,"y":14}],"x":3,"y":13,"parents":[]},{"symbol":"R","children":[{"x":3,"y":16}],"x":1,"y":14,"parents":[]},{"symbol":"R","children":[{"x":3,"y":16}],"x":2,"y":14,"parents":[]},{"symbol":"R","children":[{"x":3,"y":16}],"x":3,"y":14,"parents":[]}],"room_type":"MonsterRoom"}}
  • CommunicationMod then waits for a message back from the external process, containing a command to be executed. Possible commands are:
    • START PlayerClass [AscensionLevel] [Seed]
      • Starts a new game with the selected class, on the selected Ascension level (default 0), with the selected seed (random seed if omitted).
      • Seeds are alphanumeric, as displayed in game.
      • This and all commands are case insensitive.
      • Only currently available in the main menu of the game.
    • POTION Use|Discard PotionSlot [TargetIndex]
      • Uses or discards the potion in the selected slot, on the selected target, if necessary.
      • TargetIndex is the index of the target monster in the game's monster array (0-indexed).
      • Only available when potions can be used or discarded.
    • PLAY CardIndex [TargetIndex]
      • Plays the selected card in your hand, with the selected target, if necessary.
      • Only available when cards can be played in combat.
      • Currently, CardIndex is 1-indexed to match up with the card numbers in game.
    • END
      • Ends your turn.
      • Only available when the end turn button is available, in combat.
    • CHOOSE ChoiceIndex|ChoiceName
      • Makes a choice relevant to the current screen.
      • A list of names for each choice is provided in the game state. If provided with a name, the first choice index with the matching name is selected.
      • Generally, available at any point when PLAY is not available.
    • PROCEED
      • Clicks the button on the right side of the screen, generally causing the game to proceed to a new screen.
      • Equivalent to CONFIRM.
      • Available whenever the proceed or confirm button is present on the right side of the screen.
    • RETURN
      • Clicks the button on the left side of the screen, generally causing you to return to the previous screen.
      • Equivalent to SKIP, CANCEL, and LEAVE.
      • Available whenever the return, cancel, or leave buttons are present on the left side of the screen. Also used for the skip button on card reward screens.
    • KEY Keyname [Timeout]
      • Presses the key corresponding to Keyname
      • Possible keynames are: Confirm, Cancel, Map, Deck, Draw_Pile, Discard_Pile, Exhaust_Pile, End_Turn, Up, Down, Left, Right, Drop_Card, Card_1, Card_2, ..., Card_10
      • The actual keys pressed depend on the corresponding mapping in the game options
      • If no state change is detected after [Timeout] frames (default 100), Communication Mod will then transmit the new state and accept input from the game. This is useful for keypresses that open menus or pick up cards, without affecting the state as detected by Communication Mod.
      • Only available in a run (not the main menus)
    • CLICK Left|Right X Y
      • Clicks the selected mouse button at the specified (X,Y) coordinates
      • (0,0) is the upper left corner of the screen, and (1920,1080) is the lower right corner, regardless of game resolution
      • Will move your cursor to the specified coordindates
      • Timeout works the same as the CLICK command
      • Only available in a run
    • WAIT Timeout
      • Waits for the specified number of frames or until a state change is detected, then transmits the current game state (same behavior as Timeout for the CLICK and KEY commands, but no input is sent to the game)
      • Possibly useful for KEY and CLICK commands which are expected to produce multiple state changes as detected by Communication Mod
      • Only available in a run
    • STATE
      • Causes CommunicationMod to immediately send a JSON representation of the current state to the external process, whether or not the game state is stable.
      • Always available.
  • Upon receiving a command, CommunicationMod will execute it, and reply again with a JSON representation of the state of the game, when it is next stable.
  • If there was an error in executing the command, CommunicationMod will instead send an error message of the form:
{"error":"Error message","ready_for_command":True}

Known issues and limitations, to be hopefully fixed soon:

  • The full state of the Match and Keep event is not transmitted.
  • There is no feedback or state change if you attempt to take or buy a potion while your potion inventory is full. Beware!
  • Unselecting cards in hand select screens is not supported.
  • Several actions do not currently register a state change if they are performed manually in game.
  • You must manually edit the mod's config file to set the command for your external process.
  • Communication Mod has not been tested without fast mode on.

What are some of the potential applications of this mod?

  • Twitch plays Slay the Spire
  • Slay the Spire AIs
  • Streamers can display detailed information about the current run while in game

Frequently asked questions

  • How do I debug my process?

Communication Mod captures both the stderr and stdout of the external process. All messages sent to stdout are included in the game log, which is displayed in a window by ModTheSpire. All messages sent to the process by Communication Mod are also visible in the game log. The stdout of the external process is logged in a file named communication_mod_errors.log. Instead of printing debug information to stdout, try using a log file.

  • When I start the external process, the game hangs for 10 seconds, and then the external process quits. What do I do?

Communication Mod is probably not receiving a ready signal. Make sure your process sends "Ready\n" to stdout when it is ready to receive commands from Communication Mod. If this is not the problem, there is likely some issue with the command used to start the process. Check communication_mod_errors.log to help debug these kinds of issues.

  • Can I get some example code to help get started with the Communication Mod protocol?

Try looking at spirecomm, the Python package I wrote to interface with Communication Mod.

communicationmod's People

Contributors

dependabot[bot] avatar forgottenarbiter avatar jlubars avatar kronion avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

communicationmod's Issues

issues when switch the game language to others

When I switch the game language to, for example, Chinese, the ModTheSpire output information shows some errors occur with sort of character problems in this mod. Some Chinese character became [???] which normally should be the card name/potion name in Chinese.
Are there any support for those none-English language?
I already tested in MacOS and Win10, only with English the mod will run all fine.

Looking forward to your reply, thx.

state changes within the OverlayMenu don't register to CommunicationMod as a game state change

The OverlayMenu isn't officially a screen within the game, but instead a container for various elements that are shown/hidden depending on the game state. Most of the time interacting with these elements will register to CommunicationMod as a state change by virtue of changing the current screen or flipping the isScreenUp boolean in AbstractDungeon, but there are cases where this doesn't happen, particularly when having a GRID screen up. For example, when a user is selecting a card to purge in the shop, if they select a card and issue a cancel command this doesn't change the isScreenUp or screen fields in AbstractDungeon so hasDungeonStateChanged in GameStateListener will not return true. And whenever we issue a command, we flip waitingForCommand in GameStateListener to be false but it will never become true again until the user issues another command (since flipping that variable depends on the output of hasDungeonStateChanged. This is problematic for some automated clients who wait for waitingForCommand to become true again to issue another command.

CommunicationMod not available in steam workshop

Hi,

just in case you didn't know, it doesn't seem to be possible to access CommunicationMod via Steam Workshop anymore, since the new version was released. The previous version disappeared from my machine as well since it is no longer available, rendering mods which depend on CM useless. Any way you can fix this, or is this somehow steam related?

Number of times taken damage

Blood for Blood is cheaper based on the # of times the player has taken damage. Unfortunately, the game state doesn't reveal this number (unlike game_state.cards_discarded_this_turn).

Can you expose this value?

Ambiguity in readme

In Setup 3. it says "Edit your newly-created SpireConfig file", took me some time to realize that the actual file is called "config.properties"

Can't run external process

@ForgottenArbiter I have tried running spirecomm with the mod but I'm having an issue. The mod doesn't run the main.py file at all.

The main.py runs fine on its own so I'm guessing this is a mod problem.

Here is my config file:

#Sat Apr 22 11:12:53 AST 2023
command=python C\:\\spirecomm\\main.py

I have also made another script where I tried checking if the mod opens the external process where it creates a file after sending the ready signal, that way I can know if the mod has opened it but the file never gets created, unless I manually open the script of course.

Here is the list of mods I currently have:

  1. AchievementEnabler. V1.0.0 (Enabled).
  2. BaseMod. V5.52.2 (Enabled).
  3. Say the Spire. V0.4.2 (Enabled).
  4. Communication Mod. V1.2.1 (Enabled).
  5. StSLib. V2.9.0 (Disabled).
  6. The Construct. V1.1.0 (Disabled).
  7. Together in Spire. V4.2.0 (Disabled).

I have disabled StSLib because in the Communication mod status it says that I might encounter problems running it because it has been specifically tested with a specific version, but enabling it and disabling it didn't make any difference.

External Process Timeout delay

Hello, I am trying to sift through the documentation without an example program to guide me, and I am having issues that may just be my device. When I start the external process in-game, my computer lags for a moment. I believe that this is throwing off the timing for the communication mod as it is not getting a "Ready" signal in time. How would I get around this? Can I modify the default timeout period?
My code so far consists of:
import json import sys sys.stdout.write("Ready\n") #sys.stdout.flush() sys.stdout.write("START IRONCLAD 0 4LHFV1BZP8C8D\n") #sys.stdout.flush()

WAIT equivalent in the main menu?

Is there any way for the external process to tell Communication Mod to just do nothing in the main menu until the player starts a run? It looks like the WAIT command only works during the run itself, and if the external process doesn't send any command then it will time out.

Error when starting communication Mod on Ubuntu

This is the setup I start the mod with on Ubuntu 18.04:
asdasd

I am not used to mods so I might have set up something wrong.
Other mods (for instance Fruity mod) work fine.

The setup leads me to this stack trace :

Initializing mods...
 - Communication Mod
   - communicationmod.CommunicationMod
java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.evacipated.cardcrawl.modthespire.Patcher.initializeMods(Patcher.java:38)
	at com.evacipated.cardcrawl.modthespire.Loader.runMods(Loader.java:390)
	at com.evacipated.cardcrawl.modthespire.ui.ModSelectWindow.lambda$null$1(ModSelectWindow.java:265)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at basemod.BaseMod.subscribeIfInstance(BaseMod.java:2628)
	at basemod.BaseMod.subscribe(BaseMod.java:2648)
	at communicationmod.CommunicationMod.<init>(CommunicationMod.java:53)
	at communicationmod.CommunicationMod.initialize(CommunicationMod.java:77)
	... 8 more

Energy bugfix is not included in the latest release

Hey, can you release a new version that includes 5c9bdc4?

The energy values currently reported in https://github.com/ForgottenArbiter/CommunicationMod/releases/tag/v0.7.0 were confusing me when trying to understand the output, and makes it more difficult to write an AI. Based on the commit description I assume the linked commit is a fix that reports the current energy instead of the "max". (Still having the max value available somewhere might also be nice, but of course much less important.)

Thanks!

SpireConfig does not exist

The SpireConfig file that needs to be editted to point the mod at an external process doesn't seem to exist when ModTheSpire is installed from the steam workshop. At least, I can't seem to find it and the linked documentation does not seem to apply.

External process timed out

Hello, probably its me that is bad or your instructions need to be clearer.
When i start the mod i get the error messege that it has not recieved "the signal" from external process in is shutting down.

I took three pictures. Please explain to me what im doint wrong. One picture is of my config file, one is of ingame menu and one is the error messege from "ModTheSpire".

Thanks for the help beforehand, if i get this mod working it will be usefull!

Config
ingame
modthespire

CommunicationMod hangs if Match and Keep! choices are selected too quickly

CommunicationMod hangs if spirecomm selects choose 0 too quickly (i.e. with no-ux version of SuperFastMode). One card is chosen, and then communicationmod gets stuck while the game displays "Remaining Attempts: 4", never sending a new game state after the latest choose 0 command.

I can consistently reproduce this with

result = coordinator.play_one_game(PlayerClass.IRONCLAD, seed="2TQ7CH7RF8M2H")

when SuperFastMode 999.0.0 is set to make some actions instant + increase speed to 1000%.

It doesn't hang if I disable instant actions and play at 100% speed, and doesn't hang if I play with SuperFastMode but add a small delay to def handle_screen(self):

[...]
else:
    time.sleep(0.07)  # Add a small delay before sending the choice to communicationmod
    return ChooseAction(0)
[...]

ModVersion Info:

  • Java version (1.8.0_252)
  • Slay the Spire (07-30-2020)
  • ModTheSpire (3.16.0)

Mod list:

  • basemod (5.23.3)
  • CommunicationMod (1.0.2)
  • mintyspire (2.1.0)
  • permNeow (1)
  • superfastmode (999.0.0)

communicationmod-hangs-on-match-and-keep-SlayTheSpire.log

Screenshot 2020-10-25 at 22 31 33

Supported features for an audio-only version of STS

Hello,

I am planning to write an audio-only interface for STS with the help of Communication Mod, for blind and visually impaired gamers.

I understand that at the moment, only regular games are supported. Are there plans to add other modes, e.g. Daily Run?

The complete match state, as I understand, is not yet available. Could you please describe what is currently missing?

Are there other things in general that the Communication Mod could access? For example the settings menu, achievements, patch notes, Compendium and Potion Lab, etc. I am currently trying to gauge how much of the game could be potentially available.

Since you are more familiar with game internals, do you think it would be better to create this interface as a mod, i.e. am I limited if I create this in a non-JVM language?

Thank you very much in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.